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.

TMS320F28035: I2C Slave Device Read Problem

Part Number: TMS320F28035
Other Parts Discussed in Thread: CONTROLSUITE, TMDSCNCD28035ISO

Hello TI experts.

I am having a problem with a slave device code. I am trying to communicate two f28035 via I2C. I managed to work write function but I cant read from slave device. I checked with oscilloscope and after the slave address slave sends nack and bus stucks at busy. How can I fix this? I used PMBus example from controlsuite. I will share the codes below.

MASTER SIDE

    for(;;)
    {
        switch (command)
        {
            case WRITEWORD:
                I2CMaster_Transmit(3, Master_TransmitBuffer, 0, 0);
                break;
            case READWORD:
                while (I2CMaster_NotReady());
                I2CMaster_Transmit(1, Master_TransmitBuffer, 2, Master_ReceiveBuffer);
                break;

        }

    }

SLAVE SIDE

    for(;;)
    {
        while(!I2caRegs.I2CSTR.bit.RRDY);       //wait until data ready
        command = I2caRegs.I2CDRR;   //get the received data
        StartCpuTimer0();                       // Start the timer

        switch (command)
        {
            case WRITEWORD:
                while(!I2caRegs.I2CSTR.bit.RRDY);               //wait for the data
                Slave_ReceiveBuffer[0] = I2caRegs.I2CDRR;  //get the lower byte of received data
                StopCpuTimer0();                //No timeout, so stop the timer
                ReloadCpuTimer0();              //Reload the period value (35 ms timeout)
                while(!I2caRegs.I2CSTR.bit.RRDY);               //wait for the data
                Slave_ReceiveBuffer[1] = I2caRegs.I2CDRR;  //get the upper byte of received data
                break;
            case READWORD:
                while(!I2caRegs.I2CSTR.bit.XRDY);
                I2caRegs.I2CDXR = Slave_TransmitBuffer[0];
                StopCpuTimer0();
                ReloadCpuTimer0();
                while(!I2caRegs.I2CSTR.bit.XRDY);
                I2caRegs.I2CDXR = Slave_TransmitBuffer[1];
                break;
            default:
                break;
        }

    }

  • Hi Frozen,

    In your test you have the Master write some bytes to the slave, which is successful, followed by the Master requesting bytes from the slave which you run into issues?

    To debug why the I2C slave is NACKing the slave address, I would check if your slave code execution is getting stuck at a specific spot also checking the I2C register values in the expressions window before the slave address is received. Maybe the register bit to generate a NACK is set?

    Best,

    Kevin

  • I don't think the problem is the initialization.

    MASTER SIDE

    void I2CMaster_Init(Uint16 I2CMaster_SlaveAddress, Uint16 I2CMaster_Prescale)
    {
        //Setup I2C interrupts and Cpu Timer 0 interrupt
        EALLOW; // This is needed to write to EALLOW protected registers
        PieVectTable.I2CINT1A = &i2c_master_int1a_isr;
        PieVectTable.TINT0 = &cpu_timer0_isr;
        EDIS;   // This is needed to disable write to EALLOW protected registers
        // Enable I2C interrupt 1 in the PIE: Group 8 interrupt 1
        PieCtrlRegs.PIEIER8.bit.INTx8 = 1;
        // Enable TINT0 in the PIE: Group 1 interrupt 7
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
        // Enable CPU INT8 which is connected to PIE group 8
        IER |= M_INT8;
        // Enable CPU int1 which is connected to CPU-Timer 0
        IER |= M_INT1;
    
        InitI2CGpio();
        InitCpuTimers();
    
        ConfigCpuTimer(&CpuTimer0, 60, 35000);          //CPU Timer 0 interrupt after 35 ms (at 60MHz CPU freq.)
    
        // Initialize I2C
        I2caRegs.I2CSAR = I2CMaster_SlaveAddress;       // Slave Address.
        I2caRegs.I2COAR = 1;                       // address as Master.
        I2caRegs.I2CPSC.all = I2CMaster_Prescale;       // Prescaler - need 7-12 Mhz on module clk
        I2caRegs.I2CCLKL = 10;                          // NOTE: must be non zero
        I2caRegs.I2CCLKH = 5;                           // NOTE: must be non zero
        I2caRegs.I2CIER.all = 0x2C;                     // Enable SCD & ARDY interrupts
    
        I2caRegs.I2CMDR.bit.IRS = 1;                    // Take I2C out of reset
                                                        // Stop I2C when suspended
    
        I2caRegs.I2CFFTX.all = 0x6000;                  // Enable FIFO mode and TXFIFO
        return;
    }

    SLAVE SIDE

    void I2CSlave_Init(Uint16 I2CSlave_OwnAddress)
    {
        //Setup Cpu Timer 0 interrupt
        EALLOW; // This is needed to write to EALLOW protected registers
        PieVectTable.TINT0 = &cpu_timer0_isr;
        EDIS;   // This is needed to disable write to EALLOW protected registers
        // Enable TINT0 in the PIE: Group 1 interrupt 7
        PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
        // Enable CPU int1 which is connected to CPU-Timer 0
        IER |= M_INT1;
    
        InitI2CGpio();
        InitCpuTimers();
    
        ConfigCpuTimer(&CpuTimer0, 60, 35000);  //CPU Timer 0 interrupt after 35 ms (at 60MHz CPU freq.)
    
        // Initialize I2C
        I2caRegs.I2COAR = I2CSlave_OwnAddress;      // Own address
        I2caRegs.I2CPSC.all = 9;        // Prescaler - need 7-12 Mhz on module clk
        I2caRegs.I2CCLKL = 10;          // NOTE: must be non zero
        I2caRegs.I2CCLKH = 5;           // NOTE: must be non zero
    
        I2caRegs.I2CIER.all = 0x00;     // Clear interrupts - polling based method
    
        I2caRegs.I2CMDR.all = 0x0020;   // Take I2C out of reset
                                        // Stop I2C when suspended
        return;
    }
  • I resolved myself. The problem was TMDSCNCD28035ISO was working on ram.