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

XC161CJ and I2C

Hi Everybody,

I'm experimenting with Infineon's XC161CJ-controller on an Infineon SK-XC16x starter kit. Most of my routines work now, except the I2C-routines. Sending of data works OK, but the errors occur when I want to receive data.

Has anybody on this forum written I2C-routines for this controller? And if so, are you willing to share them?

Thanks in advance. :)

Kind Regards,
Dennis Ebben

Parents
  • Hi Henrik

    This is the software I finally succeed. I don't remmember exactly what I did but here you have it

    Best Regards
    Lluìs

    //==========================================================
    //
    void I2C_vEndTrans ()
    {
    I2C_vGenStopCond (); // Generate Stop (Clear BUM)
    I2C_ubResetStatus (I2C_IRQD | I2C_IRQP | I2C_IRQE); // Clear IRQD, IRQP, IRQE
    while (I2C_uwGetStatus () & I2C_BB); // Wait for Idle Bus
    }

    //==========================================================
    //
    ubyte I2C_ubCheckEnd ()
    {
    delay (1);
    while ((I2C_uwGetStatus () & I2C_IRQD) == 0x0000); // Wait for end of TX (IRQD)
    if (I2C_uwGetStatus () & I2C_LRB) return 1; // Check for ACK (LRB)
    return 0;
    }

    //==========================================================
    //
    void I2C_vWaitRx ()
    {
    delay (1);
    while ((I2C_uwGetStatus () & I2C_IRQD) == 0x0000); // Wait for end of RX (IRQD)
    }

    //==========================================================
    //
    ubyte I2C_EEPRD (uword add, uword *dat)
    {
    if (I2C_uwGetStatus () & I2C_BB) return EEP_BUSY; // Check if Bus is busy (BB)
    I2C_ubResetStatus (I2C_AL | I2C_IRQD | I2C_IRQP | I2C_IRQE); // Reset Status Register

    add <<= 1; // Convert address of word to address of byte
    I2C_vGenStartCond (); // Generate Start (Set BUM) START

    I2C_vWriteData ((EEPDEVADD << 1) | WRBIT); // Write Slave Address and WR CONTROL WRITE
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK ACK

    I2C_vWriteData (HIGHBYTE (add)); // Write Address (High Byte) ADDRESS HIGH
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK ACK

    I2C_vWriteData (LOWBYTE (add)); // Write Address (Low Byte) ADDRESS LOW
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK ACK

    I2C_vGenRSC (); // Repeated Start (Set RSC) START

    I2C_vWriteData ((EEPDEVADD << 1) | RDBIT); // Write Slave Address and RD CONTROL READ
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK ACK

    I2C_vSetDataDirRx (); // Disable (Tx (Clear TRX)
    I2C_vEnableACK (); // ACK for all bytes except last one
    I2C_uwReadData (); // Start Rx Clock
    I2C_vWaitRx (); // Wait Low Byte received
    I2C_vDisableACK (); // NACK for last byte
    I2C_vStopAfterTransmission (); // Generate Stop after Rx (Set STP)
    *dat = I2C_uwReadData (); // Read Low Data Byte and Start new Rx Clock
    I2C_vWaitRx (); // Wait High Byte Received
    *dat |= I2C_uwReadData () << 8; // Read High Data Byte
    I2C_vEndTrans (); // Wait End transmission
    return EEP_OK; // Done
    }

    //==========================================================
    //
    ubyte I2C_ubAckPoll ()
    {
    ubyte i, s;

    s = 1;
    for (i = 0; i < 20; i++)
    {
    I2C_vGenStopCond (); // Generate Stop (Clear BUM)
    delay (2000); // don't stress the 24LC256
    I2C_vGenStartCond (); // Generate Start (Set BUM)
    I2C_vWriteData ((EEPDEVADD << 1) | WRBIT); // Write Slave Address and WR
    if (!I2C_ubCheckEnd ()) {s = 0; break;} // If ACK then writing is done
    }
    return s;
    }

    //==========================================================
    //
    ubyte I2C_EEPWR (uword add, uword *dat, ubyte cnt)
    {
    ubyte i;

    if (!cnt) return EEP_OK; // Nothing to write
    if (I2C_uwGetStatus () & I2C_BB) return EEP_BUSY; // Check if Bus is busy (BB)
    I2C_ubResetStatus (I2C_AL | I2C_IRQD | I2C_IRQP | I2C_IRQE); // Reset Status Register

    add <<= 1;
    I2C_vGenStartCond (); // Generate Start (Set BUM)

    I2C_vWriteData ((EEPDEVADD << 1) | WRBIT); // Write Slave Address and WR
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK

    I2C_vWriteData (HIGHBYTE (add)); // Write Address (High Byte)
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK

    I2C_vWriteData (LOWBYTE (add)); // Write Address (Low Byte)
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK

    for (i = 0; i < cnt; i++) // For each data byte
    {
    I2C_vWriteData (LOWBYTE (*dat)); // Write Low Data Byte
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK

    I2C_vWriteData (HIGHBYTE (*dat)); // Write High Data Byte
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK
    }
    if (I2C_ubAckPoll ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check Acknowledge polling
    I2C_vEndTrans (); // Wait End transmission
    return EEP_OK; // Done
    }

Reply
  • Hi Henrik

    This is the software I finally succeed. I don't remmember exactly what I did but here you have it

    Best Regards
    Lluìs

    //==========================================================
    //
    void I2C_vEndTrans ()
    {
    I2C_vGenStopCond (); // Generate Stop (Clear BUM)
    I2C_ubResetStatus (I2C_IRQD | I2C_IRQP | I2C_IRQE); // Clear IRQD, IRQP, IRQE
    while (I2C_uwGetStatus () & I2C_BB); // Wait for Idle Bus
    }

    //==========================================================
    //
    ubyte I2C_ubCheckEnd ()
    {
    delay (1);
    while ((I2C_uwGetStatus () & I2C_IRQD) == 0x0000); // Wait for end of TX (IRQD)
    if (I2C_uwGetStatus () & I2C_LRB) return 1; // Check for ACK (LRB)
    return 0;
    }

    //==========================================================
    //
    void I2C_vWaitRx ()
    {
    delay (1);
    while ((I2C_uwGetStatus () & I2C_IRQD) == 0x0000); // Wait for end of RX (IRQD)
    }

    //==========================================================
    //
    ubyte I2C_EEPRD (uword add, uword *dat)
    {
    if (I2C_uwGetStatus () & I2C_BB) return EEP_BUSY; // Check if Bus is busy (BB)
    I2C_ubResetStatus (I2C_AL | I2C_IRQD | I2C_IRQP | I2C_IRQE); // Reset Status Register

    add <<= 1; // Convert address of word to address of byte
    I2C_vGenStartCond (); // Generate Start (Set BUM) START

    I2C_vWriteData ((EEPDEVADD << 1) | WRBIT); // Write Slave Address and WR CONTROL WRITE
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK ACK

    I2C_vWriteData (HIGHBYTE (add)); // Write Address (High Byte) ADDRESS HIGH
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK ACK

    I2C_vWriteData (LOWBYTE (add)); // Write Address (Low Byte) ADDRESS LOW
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK ACK

    I2C_vGenRSC (); // Repeated Start (Set RSC) START

    I2C_vWriteData ((EEPDEVADD << 1) | RDBIT); // Write Slave Address and RD CONTROL READ
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK ACK

    I2C_vSetDataDirRx (); // Disable (Tx (Clear TRX)
    I2C_vEnableACK (); // ACK for all bytes except last one
    I2C_uwReadData (); // Start Rx Clock
    I2C_vWaitRx (); // Wait Low Byte received
    I2C_vDisableACK (); // NACK for last byte
    I2C_vStopAfterTransmission (); // Generate Stop after Rx (Set STP)
    *dat = I2C_uwReadData (); // Read Low Data Byte and Start new Rx Clock
    I2C_vWaitRx (); // Wait High Byte Received
    *dat |= I2C_uwReadData () << 8; // Read High Data Byte
    I2C_vEndTrans (); // Wait End transmission
    return EEP_OK; // Done
    }

    //==========================================================
    //
    ubyte I2C_ubAckPoll ()
    {
    ubyte i, s;

    s = 1;
    for (i = 0; i < 20; i++)
    {
    I2C_vGenStopCond (); // Generate Stop (Clear BUM)
    delay (2000); // don't stress the 24LC256
    I2C_vGenStartCond (); // Generate Start (Set BUM)
    I2C_vWriteData ((EEPDEVADD << 1) | WRBIT); // Write Slave Address and WR
    if (!I2C_ubCheckEnd ()) {s = 0; break;} // If ACK then writing is done
    }
    return s;
    }

    //==========================================================
    //
    ubyte I2C_EEPWR (uword add, uword *dat, ubyte cnt)
    {
    ubyte i;

    if (!cnt) return EEP_OK; // Nothing to write
    if (I2C_uwGetStatus () & I2C_BB) return EEP_BUSY; // Check if Bus is busy (BB)
    I2C_ubResetStatus (I2C_AL | I2C_IRQD | I2C_IRQP | I2C_IRQE); // Reset Status Register

    add <<= 1;
    I2C_vGenStartCond (); // Generate Start (Set BUM)

    I2C_vWriteData ((EEPDEVADD << 1) | WRBIT); // Write Slave Address and WR
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK

    I2C_vWriteData (HIGHBYTE (add)); // Write Address (High Byte)
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK

    I2C_vWriteData (LOWBYTE (add)); // Write Address (Low Byte)
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK

    for (i = 0; i < cnt; i++) // For each data byte
    {
    I2C_vWriteData (LOWBYTE (*dat)); // Write Low Data Byte
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK

    I2C_vWriteData (HIGHBYTE (*dat)); // Write High Data Byte
    if (I2C_ubCheckEnd ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check for ACK
    }
    if (I2C_ubAckPoll ()) {I2C_vEndTrans (); return EEP_NOTOK;} // Check Acknowledge polling
    I2C_vEndTrans (); // Wait End transmission
    return EEP_OK; // Done
    }

Children