This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

F28335 I2C slave

Other Parts Discussed in Thread: TEST

dear all,

 

I am facing a problem with the I2C of the F28335. The DSP is configured as a slave. I do that in my code :

 

void InitI2CGpio()
{

   EALLOW;
/* Enable internal pull-up for the selected pins */
// Pull-ups can be enabled or disabled disabled by the user. 
// Comment out other unwanted lines.

    GpioCtrlRegs.GPBPUD.bit.GPIO32 = 1;    // Disable pull-up for GPIO32 (SDAA)
    GpioCtrlRegs.GPBPUD.bit.GPIO33 = 1;       // Disnable pull-up for GPIO33 (SCLA)

/* Set qualification for selected pins to asynch only */
// This will select asynch (no qualification) for the selected pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;  // Asynch input GPIO32 (SDAA)
    GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;  // Asynch input GPIO33 (SCLA)

/* Configure SCI pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be I2C functional pins.
// Comment out other unwanted lines.

    GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;   // Configure GPIO32 for SDAA operation
    GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;   // Configure GPIO33 for SCLA operation
   
    EDIS;

}

void InitI2C(void)
{

    I2caRegs.I2CMDR.bit.IRS  = 0;        // put I2C module in reset

    // For 30 MHz SYSCLKOUT
    I2caRegs.I2CPSC.all = 2;            // Prescaler - need 7-12 Mhz on module clk (30/3 = 10MHz)
    I2caRegs.I2CIER.all = 0x44;            // Enable AAS & ARDY interrupts

       // Initialize I2C
       I2caRegs.I2COAR = 0x0002;            // Slave address du DSP en Slave mode

       I2caRegs.I2CFFTX.all = 0x6000;        // Enable FIFO mode and TXFIFO
       I2caRegs.I2CFFRX.all = 0x2060;        // Enable RXFIFO, clear RXFFINT,

      I2caRegs.I2CMDR.bit.FDF  = 0;        // free data format is disabled
       I2caRegs.I2CMDR.bit.XA   = 0;        // 7 bits address bit
       I2caRegs.I2CMDR.bit.MST  = 0;        // Slave mode

      I2caRegs.I2CMDR.bit.IRS = 1;        // Take I2C out of reset


       return;
}

 

 

That s it for the configuration. Then in main program I do :

 

    EALLOW;
    PieVectTable.I2CINT1A    = &i2c_int1a_isr;
    EDIS;

    PieCtrlRegs.PIECTRL.bit.ENPIE = 1;    // Enable the PIE block

     // Enable I2C interrupt 1  in the PIE: Group 8
   PieCtrlRegs.PIEIER8.bit.INTx1 = 1;

    // Enable CPU INT8 which is connected to PIE group 8
   IER |= M_INT8;

 

interrupt void i2c_int1a_isr(void)     // I2C-A
{
   Uint16 IntSource;

   // Read interrupt source
   IntSource = I2caRegs.I2CISRC.all;

   // Read interrupt read as slave
    if(IntSource == I2C_AAS_ISRC)
    {
 
        I2caRegs.I2CCNT = I2C_NUMBYTES;
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[0];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[1];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[2];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[3];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[4];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[5];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[6];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[7];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[8];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[9];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[10];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[11];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[12];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[13];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[14];
        I2caRegs.I2CDXR = CurrentMsgPtr->MsgBuffer[15];
    }

   else
   {
      // Generate some error due to invalid interrupt source
      asm("   ESTOP0");
   }

   // Enable future I2C (PIE Group 8) interrupts
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
}

 

When I get a read request from the I2C master the data readback by the master are not MsgBuffer[0] to MsgBuffer[15], ther is a shift in the data, and the value of MsgBuffer[0] read by the master is changing from time to time.

Any ideas of what my problem might be ?

Thanks a millions for any idea.

 

 

 

 

  • Did you try sending data across without the FIFO enabled?

    In the ISR-

    if AAS = 1 {

    repeat 15 LOOP

    Wait till XRDY=1

    I2CDXR = next value

    LOOP

    }

  • with fifo disabled the behavior is different, but does not work either : if I do that :

     

    interrupt void i2c_int1a_isr(void)     // I2C-A
    {
       Uint16 IntSource,  i;


     IntSource = I2caRegs.I2CISRC.all;
       
        // addressed as a slave
     if( IntSource == I2C_AAS_ISRC)
     {

      for(i=0; i < I2C_NUMBYTES; i++)
            {

       IntSource = I2caRegs.I2CISRC.all;
       while (IntSource == I2C_NO_ISRC)
       {
        IntSource = I2caRegs.I2CISRC.all; 
       }

       switch (IntSource)
       {
        default:
        break;

        case I2C_TX_ISRC:
        {
        I2caRegs.I2CDXR = I2CMsgBuffer[i];     
        }
        break;

        case I2C_RX_ISRC:
        {
        I2CMsgBuffer[i] = I2caRegs.I2CDRR;
        }
        break;

        case I2C_SCD_ISRC:
        {
        i = I2C_NUMBYTES;
        }
        break;
       }
      }
     }

       else
        {
           // Generate some error due to invalid interrupt source
      asm("   ESTOP0");
     }

       // Enable future I2C (PIE Group 8) interrupts
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
    }

    with a breakpoint in asm("   ESTOP0"), I have IntSource = 0 and i=24

    I can hardly see how it is possible to enter the ISR and to have  IntSource = 0 

     

    ???.

     

  • Wauters,

    I was reading the datasheet and the INTCODE bit field is cleared every time its read from the CPU. It could be that when an interrupt comes it INTCODE is set with the right opcode but when you get into the ISR it is being inadvertantly read before you get to reading it. Could you post the disassembly for ISR.

    As a test dont do the if then loops but just directly read the I2CDRR to see if the expected value is in there

  • Hi all,

     

    with this code the F28335 works grand as a I2C slave !

     

    interrupt void i2c_int1a_isr(void)     // I2C-A
    {
       Uint16 I2CADDRESS_VALUE, I2CADDRESS_RECUE;

        // addressed as a slave by TRT200
        if( I2caRegs.I2CISRC.all == I2C_AAS_ISRC)
        {
            // adresse I2C pas encore recue
            I2CADDRESS_RECUE = 0;
            I2CADDRESS_VALUE = 0;
            // lecture ou écriture jusqu'à réception d'un STOP
            while (I2caRegs.I2CSTR.bit.SCD == 0)
            {
                // TRT200 vient lire les données
                if (I2caRegs.I2CSTR.bit.XRDY == 1)
                {
                    I2caRegs.I2CDXR = I2CMsgBuffer[++I2CADDRESS_VALUE];
                }
                else if (I2caRegs.I2CSTR.bit.RRDY == 1)
                {
                    // première data recu : adresse
                    if (I2CADDRESS_RECUE == 0)
                    {
                        I2CADDRESS_VALUE = I2caRegs.I2CDRR;
                        I2CADDRESS_RECUE = 1;
                        I2caRegs.I2CDXR = I2CMsgBuffer[I2CADDRESS_VALUE];               
                    }
                    else
                    {
                        I2CMsgBuffer[I2CADDRESS_VALUE] = I2caRegs.I2CDRR;
                    }
                }
            }
        // On reset la condition STOP détectée
        I2caRegs.I2CSTR.bit.SCD  = 1;
        }
          else
           {
              // Generate some error due to invalid interrupt source
            asm("   ESTOP0");
        }

           // Enable future I2C (PIE Group 8) interrupts

           PieCtrlRegs.PIEACK.all = PIEACK_GROUP8;
    }