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.

TMS320F28069: I2C Communications working in debug code fails in release code

Part Number: TMS320F28069

Hi All,

Still working on the project to add I2C communications to an existing product which uses the TMS320F28069.

The 28069 is a slave.  It responds to quite a number of I2C requests for individual data registers sized between 3 and 4 bytes.  Plus, there is one request that asks for all data registers at once.  That one contains 96 data bytes in addition to the register address and a byte that tells the master how many bytes to expect.

This works perfectly, first time every time, when compiled and run in the debug configuration with the programmer/emulator connected.

Release configuration compiles without a problem and all of the product's functions operate normally, including all the individual I2C data requests.  But the one request for all registers doesn't work.

I think what's happening is that the 28069 is taking so long to gather the data to send that the master times out and clears the bus.  If that's it, should I be pulling the clock line low to stretch the clock until the 28069 is ready to send all data?  What's a good way to do that?

Still that doesn't explain (to me anyway) how the system works fine in the debug configuration.

Stated concisely, in the debug configuration the I2C request for 99 bytes works perfectly, in the release configuration the 99 byte request fails.

Is this more likely a code problem, compile problem, I2C timing problem, optimization settings problem, or something different?

Thank in advance,
robin

  • ADDITIONAL INFORMATION:

    When the slave receives the write command from the master (the first two bytes in the analyzer readout), it goes off and starts collecting all the data and placing it in the transmit buffer (an array I created, not an I2C module register).  After collecting ALL the data and placing it in the transmit buffer, it's sent out by sequentially placing each byte in the I2CDXR.

    Here's an image of the I2C bus when running the debug configuration:  (responds correctly)

    Here's an image in release configuration:  (doesn't respond correctly)

    The slave isn't pulling the data line low for the ACK bit, so the master sees a NACK.  The master thinks it's done and moves on to the next task.

    Should the slave hold the clock line low immediately after the R/W clock bit (8th bit) of the master's read command?  Or should it first issue an ACK and then hold the clock low?

    Please let me know if my assumptions are faulty.

    Thanks,
    robin

  • Hi Robin,

    That's good to hear that you've managed to make a lot of progress. I think it could be a number of things causing this issue and we'll need to further debug the issue to really say what's going wrong.

    Robin Vice said:
    I think what's happening is that the 28069 is taking so long to gather the data to send that the master times out and clears the bus. 

    Have you looked at waveforms to understand the state of the bus after an extensive period of time? Does SDA/SCL eventually stop being pulled low before the slave responds to the master device?

    Robin Vice said:
    Stated concisely, in the debug configuration the I2C request for 99 bytes works perfectly, in the release configuration the 99 byte request fails.

    This is an important point. When running the 'release' configuration are you still able to have a debugger connected? i.e. running from flash config, but still debugging in CCS over JTAG? I think this would be a good thing to try, debugging both the slave and master sides together to understand what's going on at each device.

    Are there any notable differences between your debug and release project versions SW?

    Best,

    Kevin

  • AND MORE INFORMATION:

    Here are snippets of code that might be relevant:

    I2C Module Initialization:

    void InitI2C1(void)
    {
        // Initialize I2C
        I2caRegs.I2CMDR.bit.IRS         = 0;                // Put I2C module in reset while making changes
    
        I2caRegs.I2COAR                 = I2C_SLAVE_ADDR;   // Own address = 0x26
    
        I2caRegs.I2CIER.bit.AAS         = 0;                // 1 = Addressed as slave interrupt request enabled
        I2caRegs.I2CIER.bit.SCD         = 0;                // 1 = Stop condition detected interrupt request enabled
        I2caRegs.I2CIER.bit.XRDY        = 1;                // 1 = Transmit data ready interrupt request disabled
        I2caRegs.I2CIER.bit.RRDY        = 1;                // 1 = W1C - Receive data ready interrupt request enabled
        I2caRegs.I2CIER.bit.ARDY        = 0;                // 1 = Master Only - Register access ready interrupt request enabled
        I2caRegs.I2CIER.bit.NACK        = 0;                // 0 = W1C - No-ack interrupt request disabled
        I2caRegs.I2CIER.bit.ARBL        = 0;                // 0 = W1C - Arbitration lost interrupt request disabled
    
        I2caRegs.I2CSTR.bit.SDIR        = 1;                // W1C - Slave direction bit 0 = not addressed as slave transmitter
        I2caRegs.I2CSTR.bit.NACKSNT     = 1;                // W1C - NACK sent bit 0 = NACK not sent
    //r.o.    I2caRegs.I2CSTR.bit.BB          = 1;                // Busy bit (read only) 0 = bus free
    //r.o.    I2caRegs.I2CSTR.bit.RSFULL      = 1;                // 1 = receive shift register overrun condition detected
    //r.o.    I2caRegs.I2CSTR.bit.XSMT        = 1;                // 0 = transmit shift register underflow detected (empty)
    //r.o.    I2caRegs.I2CSTR.bit.AAS         = 1;                // 1 = I2C module recognized its own slave address
    //r.o.    I2caRegs.I2CSTR.bit.AD0         = 1;                // 1 = address of all zeros (general call) was detected
        I2caRegs.I2CSTR.bit.SCD         = 1;                // W1C - 1 = stop condition was detected
    //r.o.    I2caRegs.I2CSTR.bit.XRDY        = 1;                // 1 = Ready for more transmit data to go in I2CDXR
        I2caRegs.I2CSTR.bit.RRDY        = 1;                // W1C - Receive data ready int flag 1 = data is in I2CDRR
        I2caRegs.I2CSTR.bit.ARDY        = 1;                // W1C - Master Only - Register access ready int flag
        I2caRegs.I2CSTR.bit.NACK        = 1;                // W1C - 1 = NACK received
        I2caRegs.I2CSTR.bit.ARBL        = 1;                // W1C - 1 = arbitration lost
    
        // Setup I2C data rate
        I2caRegs.I2CPSC.bit.IPSC        = 9;                // Prescaler value 90mHz SYSCLK / 9 = 10mHz
    
        // 10mHz / 100 = 100kHz fr comm's with master)
        I2caRegs.I2CCLKL                =  62;               // 62 + 5 = 67
        I2caRegs.I2CCLKH                =  28;               // 28 + 5 = 33        -->  33 + 67 = 100
    
        // 10mHz / 200 = 50kHz (for 2x16 display)
    //    I2caRegs.I2CCLKL                = 131;               // 131 + 5 = 136
    //    I2caRegs.I2CCLKH                =  59;               //  59 + 5 =  64      --> 136 + 64 = 200
    
        I2caRegs.I2CCNT                 = 1;                // Set data count (ignored in RM mode)
                                                            // Stays at 1 while in slave-receive mode.
                                                            // Is changed to actual number of bytes to transfer when in
                                                            // slave-transmit mode.
    
        I2caRegs.I2CSAR                 = I2C_MASTER_ADDR;  // Master only - Address to which next data will be transmitted by this slave
    
        I2caRegs.I2CMDR.bit.NACKMOD     = 0;                // NACK mode
        I2caRegs.I2CMDR.bit.FREE        = 0;                // For debugging: 0 = I2C halts during interrupts
        I2caRegs.I2CMDR.bit.STT         = 0;                // Master only - Start bit
        I2caRegs.I2CMDR.bit.STP         = 0;                // Master only - Stop bit
        I2caRegs.I2CMDR.bit.MST         = 0;                // Remains 0 for slave mode.  1 = Master mode
        I2caRegs.I2CMDR.bit.TRX         = 0;                // 0 = Receive mode
        I2caRegs.I2CMDR.bit.XA          = 0;                // 0 = 7 bit address mode
        I2caRegs.I2CMDR.bit.RM          = 0;                // 1 = repeat mode
        I2caRegs.I2CMDR.bit.DLB         = 0;                // 0 = Digital loopback mode disabled
        I2caRegs.I2CMDR.bit.STB         = 0;                // Master only - Start Byte mode
        I2caRegs.I2CMDR.bit.FDF         = 0;                // Keep at 0. Free data format mode
        I2caRegs.I2CMDR.bit.BC          = 0;                // Set bit count to 8 bits (0 = 8)
    
        I2caRegs.I2CEMDR.bit.BC         = 0;                // Backwards compatibility mode
    
        I2caRegs.I2CFFTX.bit.I2CFFEN    = 0;                // 1 = Enable transmit & receive FIFOs
        I2caRegs.I2CFFTX.bit.TXFFRST    = 0;                // 1 = Take transmit FIFO out of reset
    //r.o.    I2caRegs.I2CFFTX.bit.TXFFST     = 0;                // How many bytes are in the transmit FIFO
    //r.o.    I2caRegs.I2CFFTX.bit.TXFFINT    = 0;                // 1 = interrupt occurred
        I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;                // W1C - Clears transmit interrupt flag (do again after irs = 1
        I2caRegs.I2CFFTX.bit.TXFFIENA   = 0;                // 0 = Disable transmit FIFO interrupt
        I2caRegs.I2CFFTX.bit.TXFFIL     = 1;                // Set the transmit FIFO interrupt Threshold
    
        I2caRegs.I2CFFRX.bit.RXFFRST    = 0;                // 1 = enable receive FIFO operation
    //r.o.    I2caRegs.I2CFFRX.bit.RXFFST     = 0;                // Bytes in receive FIFO
        I2caRegs.I2CFFRX.bit.RXFFINT    = 0;                // Receive interrupt flag 1 = int
        I2caRegs.I2CFFRX.bit.RXFFINTCLR = 1;                // Write 1 to clear receive int flag
        I2caRegs.I2CFFRX.bit.RXFFIENA   = 0;                // 1 = receive interrupt is enabled
        I2caRegs.I2CFFRX.bit.RXFFIL     = 1;                // Set the receive FIFO interrupt level
    
        I2caRegs.I2CMDR.bit.IRS         = 1;                // I2C module is re-enabled after making changes
    
        I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;                // Clears transmit interrupt flag
        I2caRegs.I2CFFRX.bit.RXFFINTCLR = 1;                // Clears receive interrupt flag
    }
    

    Interrupt service routine:

    i2c_int1a_isr(void)
    {
        // If receive interrupt flag is set, read data & call parser
          if(I2caRegs.I2CSTR.bit.RRDY)
        {
              receiveCounter++;
              I2C_Parser(I2caRegs.I2CDRR);
              receiveCounter--;
        }
    
        // If transmit interrupt flag is set, put data in the buffer
          else if(I2caRegs.I2CSTR.bit.XRDY)
        {
              I2caRegs.I2CDXR = 0xdb;
        }
    
        PieCtrlRegs.PIEACK.bit.ACK8 = 1;    // Issue ACK
    }
    

    Parser function:

    unsigned int I2C_Parser(unsigned int I2C_Command)
    {
        switch(I2C_Command){
            case Prod_ID: // 0x01
                I2C_Command = 0xff;
    
                I2C_Data_Regs.Product_ID.ID = PRODUCT_ID;
    
                sData[0] = Prod_ID;
                sData[1] = I2C_Data_Regs.Product_ID.byteQty;
                sData[2] = I2C_Data_Regs.Product_ID.ID;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case FW_Ver:  // 0x02
                I2C_Command = 0xff;
    
                I2C_Data_Regs.FW_Version.FW_Ver = CODE_VERSION;
    
                sData[0] = FW_Ver;
                sData[1] = I2C_Data_Regs.FW_Version.byteQty;
                sData[2] = I2C_Data_Regs.FW_Version.FW_Ver;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case Sw_Bitfield:  // 0x03
                I2C_Command = 0xff;
    
                I2C_Data_Regs.Switches_Union.bField_Byte  = 0;
    
                I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.PP_Sel		= PP_Enable;	// lsb
                I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.GM_Latch_Sel = GM_Latch_Enable_SW;
                I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.VFD_Sel		= VFD_SW;
                I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.ST_UVR_Sel	= ST_UVR_SW;
                I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.GM_Test_Sw	= GM_Test_SW;
                I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.GM_Reset_Sw	= GM_Reset_SW;
                I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.GFR_Reset_Sw = GFR_Reset_SW;
    
                sData[0] = Sw_Bitfield;
                sData[1] = I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.byteQty;
                sData[2] = I2C_Data_Regs.Switches_Union.bField_Byte;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case Current_Setting:  // 0x04
                I2C_Command = 0xff;
    
                I2C_Data_Regs.Current_Pot.Cur_Setting = CurrentPotSetting;
    
                sData[0] = Current_Setting;
                sData[1] = I2C_Data_Regs.Current_Pot.byteQty;
                sData[2] = I2C_Data_Regs.Current_Pot.Cur_Setting;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case Delay_Setting:  // 0x05
                I2C_Command = 0xff;
    
                int tempSetting = 0;
    
                tempSetting = GFRDelayTimer + 20;
                tempSetting &= 0xff00;
                I2C_Data_Regs.Delay_Pot.Delay_Setting_High = tempSetting >> 8;
    
                tempSetting = GFRDelayTimer + 20;
                tempSetting &= 0x00ff;
                I2C_Data_Regs.Delay_Pot.Delay_Setting_Low  = tempSetting;
    
                sData[0] = Delay_Setting;
                sData[1] = I2C_Data_Regs.Delay_Pot.byteQty;
                sData[2] = I2C_Data_Regs.Delay_Pot.Delay_Setting_High;
                sData[3] = I2C_Data_Regs.Delay_Pot.Delay_Setting_Low;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case Detector_LEDs:  // 0x06
                I2C_Command = 0xff;
    
                int tempLED = 0;
    
                I2C_Data_Regs.LEDs_Union.LED_Byte_1 = 0;
    
                (LED_matrix_Row_0 & 0x8000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.DC_Green = tempLED;
    
                (LED_matrix_Row_0 & 0x4000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.HF_Green = tempLED;
    
                (LED_matrix_Row_0 & 0x2000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.MF_Green = tempLED;
    
                (LED_matrix_Row_0 & 0x1000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.LF_Green = tempLED;
    
                (LED_matrix_Row_1 & 0x8000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.DC_Yellow = tempLED;
    
                (LED_matrix_Row_1 & 0x4000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.HF_Yellow = tempLED;
    
                (LED_matrix_Row_1 & 0x2000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.MF_Yellow = tempLED;
    
                (LED_matrix_Row_1 & 0x1000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.LF_Yellow = tempLED;
    
                (LED_matrix_Row_2 & 0x8000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.DC_Red = tempLED;
    
                (LED_matrix_Row_2 & 0x4000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.HF_Red = tempLED;
    
                (LED_matrix_Row_2 & 0x2000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.MF_Red = tempLED;
    
                (LED_matrix_Row_2 & 0x1000) ? (tempLED = 1) : (tempLED = 0);
                I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.LF_Red = tempLED;
    
                sData[0] = Detector_LEDs;
                sData[1] = I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.byteQty;
                sData[2] = I2C_Data_Regs.LEDs_Union.LED_Byte_1 >> 8;
                sData[3] = I2C_Data_Regs.LEDs_Union.LED_Byte_1;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case Trip_Status:  // 0x07
                I2C_Command = 0xff;
    
                int tempTrip = 0;
    
                I2C_Data_Regs.Trip_Status.StatusByte = GMS_Trip ? (tempTrip = 1) : (tempTrip = 0);
    
                sData[0] = Trip_Status;
                sData[1] = I2C_Data_Regs.Trip_Status.byteQty;
                sData[2] = I2C_Data_Regs.Trip_Status.StatusByte;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case Last_State_Change:  // 0x08
                I2C_Command = 0xff;
    
                I2C_Data_Regs.Last_State_Change.StateByte = calVals.lastGMSStateChange;
    
                sData[0] = Last_State_Change;
                sData[1] = I2C_Data_Regs.Last_State_Change.byteQty;
                sData[2] = I2C_Data_Regs.Last_State_Change.StateByte;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case LF_Level:  // 0x09
                I2C_Command = 0xff;
    
                I2C_Data_Regs.LF_Level.Level_Byte2 = ((lowbpfRMS * 5000) + 10);
    
                sData[0] = LF_Level;
                sData[1] = I2C_Data_Regs.LF_Level.byteQty;
                sData[2] = I2C_Data_Regs.LF_Level.Level_Byte1;
                sData[3] = I2C_Data_Regs.LF_Level.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case LF_Trip_Thresh:  // 0x0a
                I2C_Command = 0xff;
    
                I2C_Data_Regs.LF_Threshold.Level_Byte2 = ((lfThreshYellow * 5000) + 10);
    
                sData[0] = LF_Trip_Thresh;
                sData[1] = I2C_Data_Regs.LF_Threshold.byteQty;
                sData[2] = I2C_Data_Regs.LF_Threshold.Level_Byte1;
                sData[3] = I2C_Data_Regs.LF_Threshold.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case MF_Level:  // 0x0b
                I2C_Command = 0xff;
    
                I2C_Data_Regs.MF_Level.Level_Byte2 = ((midbpfRMS * 4215) + 10);
    
                sData[0] = MF_Level;
                sData[1] = I2C_Data_Regs.MF_Level.byteQty;
                sData[2] = I2C_Data_Regs.MF_Level.Level_Byte1;
                sData[3] = I2C_Data_Regs.MF_Level.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case MF_Trip_Thresh:  // 0x0c
                I2C_Command = 0xff;
    
                I2C_Data_Regs.MF_Threshold.Level_Byte2 = ((mfThreshYellow * 4215) + 10);
    
                sData[0] = MF_Trip_Thresh;
                sData[1] = I2C_Data_Regs.MF_Threshold.byteQty;
                sData[2] = I2C_Data_Regs.MF_Threshold.Level_Byte1;
                sData[3] = I2C_Data_Regs.MF_Threshold.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case HF_Level:  // 0x0d
                I2C_Command = 0xff;
    
                I2C_Data_Regs.HF_Level.Level_Byte2 = ((highbpfRMS * 4000) + 10);
    
                sData[0] = HF_Level;
                sData[1] = I2C_Data_Regs.HF_Level.byteQty;
                sData[2] = I2C_Data_Regs.HF_Level.Level_Byte1;
                sData[3] = I2C_Data_Regs.HF_Level.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case HF_Trip_Thresh:  // 0x0e
                I2C_Command = 0xff;
    
                I2C_Data_Regs.HF_Threshold.Level_Byte2 = ((hfThreshYellow * 4000) + 10);
    
                sData[0] = HF_Trip_Thresh;
                sData[1] = I2C_Data_Regs.HF_Threshold.byteQty;
                sData[2] = I2C_Data_Regs.HF_Threshold.Level_Byte1;
                sData[3] = I2C_Data_Regs.HF_Threshold.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case DC_Level_RMS:  // 0x0f
                I2C_Command = 0xff;
    
                I2C_Data_Regs.DC_Level.Level_Byte2 = ((DClpfRMS * 150) + 0);
    
                sData[0] = DC_Level_RMS;
                sData[1] = I2C_Data_Regs.DC_Level.byteQty;
                sData[2] = I2C_Data_Regs.DC_Level.Level_Byte1;
                sData[3] = I2C_Data_Regs.DC_Level.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case DC_Trip_Thresh:  // 0x10
                I2C_Command = 0xff;
    
                I2C_Data_Regs.DC_Threshold.Level_Byte2 = ((dcThreshYellow * 150) + 0);
    
                sData[0] = DC_Trip_Thresh;
                sData[1] = I2C_Data_Regs.DC_Threshold.byteQty;
                sData[2] = I2C_Data_Regs.DC_Threshold.Level_Byte1;
                sData[3] = I2C_Data_Regs.DC_Threshold.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case PP_LF_Level:  // 0x11
                I2C_Command = 0xff;
    
                I2C_Data_Regs.PP_LF_Level.Level_Byte2 = ((lowbpfRMSPP * 656) + 10);
    
                sData[0] = PP_LF_Level;
                sData[1] = I2C_Data_Regs.PP_LF_Level.byteQty;
                sData[2] = I2C_Data_Regs.PP_LF_Level.Level_Byte1;
                sData[3] = I2C_Data_Regs.PP_LF_Level.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case PP_LF_Trip_Thresh:  // 0x12
                I2C_Command = 0xff;
    
                I2C_Data_Regs.PP_LF_Threshold.Level_Byte2 = ((lfThreshPP * 656) + 10);
    
                sData[0] = PP_LF_Trip_Thresh;
                sData[1] = I2C_Data_Regs.PP_LF_Threshold.byteQty;
                sData[2] = I2C_Data_Regs.PP_LF_Threshold.Level_Byte1;
                sData[3] = I2C_Data_Regs.PP_LF_Threshold.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case PP_MF_Level:  // 0x13
                I2C_Command = 0xff;
    
                I2C_Data_Regs.PP_MF_Level.Level_Byte2 = ((midbpfRMSPP * 301) + 10);
    
                sData[0] = PP_MF_Level;
                sData[1] = I2C_Data_Regs.PP_MF_Level.byteQty;
                sData[2] = I2C_Data_Regs.PP_MF_Level.Level_Byte1;
                sData[3] = I2C_Data_Regs.PP_MF_Level.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case PP_MF_Trip_Thresh:  // 0x14
                I2C_Command = 0xff;
    
                I2C_Data_Regs.PP_MF_Threshold.Level_Byte2 = ((mfThreshPP * 301) + 10);
    
                sData[0] = PP_MF_Trip_Thresh;
                sData[1] = I2C_Data_Regs.PP_MF_Threshold.byteQty;
                sData[2] = I2C_Data_Regs.PP_MF_Threshold.Level_Byte1;
                sData[3] = I2C_Data_Regs.PP_MF_Threshold.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case PP_HF_Level:  // 0x15
                I2C_Command = 0xff;
    
                I2C_Data_Regs.PP_HF_Level.Level_Byte2 = ((highbpfRMSPP * 225) + 10);
    
                sData[0] = PP_HF_Level;
                sData[1] = I2C_Data_Regs.PP_HF_Level.byteQty;
                sData[2] = I2C_Data_Regs.PP_HF_Level.Level_Byte1;
                sData[3] = I2C_Data_Regs.PP_HF_Level.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case PP_HF_Trip_Thresh:  // 0x16
                I2C_Command = 0xff;
    
                I2C_Data_Regs.PP_HF_Threshold.Level_Byte2 = ((hfThreshPP * 225) + 10);
    
                sData[0] = PP_HF_Trip_Thresh;
                sData[1] = I2C_Data_Regs.PP_HF_Threshold.byteQty;
                sData[2] = I2C_Data_Regs.PP_HF_Threshold.Level_Byte1;
                sData[3] = I2C_Data_Regs.PP_HF_Threshold.Level_Byte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case LF_Freq:  // 0x17
                I2C_Command = 0xff;
    
                I2C_Data_Regs.LF_Frequency.FreqByte1 = (_IQint(freqLow + 0.5)) >> 8;
                I2C_Data_Regs.LF_Frequency.FreqByte2 = _IQint(freqLow + 0.5);
    
                sData[0] = LF_Freq;
                sData[1] = I2C_Data_Regs.LF_Frequency.byteQty;
                sData[2] = I2C_Data_Regs.LF_Frequency.FreqByte1;
                sData[3] = I2C_Data_Regs.LF_Frequency.FreqByte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case MF_Freq:  // 0x18
                I2C_Command = 0xff;
    
                I2C_Data_Regs.MF_Frequency.FreqByte1 = (_IQint(freqMid + 0.5)) >> 8;
                I2C_Data_Regs.MF_Frequency.FreqByte2 = _IQint(freqMid + 0.5);
    
                sData[0] = MF_Freq;
                sData[1] = I2C_Data_Regs.MF_Frequency.byteQty;
                sData[2] = I2C_Data_Regs.MF_Frequency.FreqByte1;
                sData[3] = I2C_Data_Regs.MF_Frequency.FreqByte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case HF_Freq:  // 0x19
                I2C_Command = 0xff;
    
                I2C_Data_Regs.HF_Frequency.FreqByte1 = (_IQint(freqHigh + 0.5)) >> 8;
                I2C_Data_Regs.HF_Frequency.FreqByte2 = _IQint(freqHigh + 0.5);
    
                sData[0] = HF_Freq;
                sData[1] = I2C_Data_Regs.HF_Frequency.byteQty;
                sData[2] = I2C_Data_Regs.HF_Frequency.FreqByte1;
                sData[3] = I2C_Data_Regs.HF_Frequency.FreqByte2;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case All_Data:  // 0x1A
                I2C_Command = 0xff;
    
    			int tempSettingAllData = 0;
    
                // Unless specified otherwise, the following data was established in I2CA_Data_Regs_Init()
                sData[0] = All_Data;
                sData[1] = I2C_Data_Regs.All_Data_Byte_Qty;
    
                sData[2] = Prod_ID;
                sData[3] = I2C_Data_Regs.Product_ID.byteQty;
                sData[4] = I2C_Data_Regs.Product_ID.ID;
    
                sData[5] = FW_Ver;
                sData[6] = I2C_Data_Regs.FW_Version.byteQty;
                sData[7] = I2C_Data_Regs.FW_Version.FW_Ver;
    
                sData[8] = Sw_Bitfield;
                sData[9] = I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.byteQty;
    				// Update bitfield now
    				I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.PP_Sel		= PP_Enable;	// lsb
    				I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.GM_Latch_Sel = GM_Latch_Enable_SW;
    				I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.VFD_Sel		= VFD_SW;
    				I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.ST_UVR_Sel	= ST_UVR_SW;
    				I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.GM_Test_Sw	= GM_Test_SW;
    				I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.GM_Reset_Sw	= GM_Reset_SW;
    				I2C_Data_Regs.Switches_Union.Sw_Bitfield_Union.GFR_Reset_Sw = GFR_Reset_SW;
                sData[10] = I2C_Data_Regs.Switches_Union.bField_Byte;
    
                sData[11] = Current_Setting;
                sData[12] = I2C_Data_Regs.Current_Pot.byteQty;
                	// Update current setting now
                	I2C_Data_Regs.Current_Pot.Cur_Setting = CurrentPotSetting;
                sData[13] = I2C_Data_Regs.Current_Pot.Cur_Setting;
    
                sData[14] = Delay_Setting;
                sData[15] = I2C_Data_Regs.Delay_Pot.byteQty;
    				// Update delay setting now
    				tempSettingAllData = GFRDelayTimer + 20;
    				tempSettingAllData &= 0xff00;
    				I2C_Data_Regs.Delay_Pot.Delay_Setting_High = tempSettingAllData >> 8;
    
    				tempSettingAllData = GFRDelayTimer + 20;
    				tempSettingAllData &= 0x00ff;
    				I2C_Data_Regs.Delay_Pot.Delay_Setting_Low  = tempSettingAllData;
                sData[16] = I2C_Data_Regs.Delay_Pot.Delay_Setting_High;
                sData[17] = I2C_Data_Regs.Delay_Pot.Delay_Setting_Low;
    
                sData[18] = Detector_LEDs;
                sData[19] = I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.byteQty;
    
    				// Update detector LEDs status now
    				int tempLEDAllData = 0;
    
    				I2C_Data_Regs.LEDs_Union.LED_Byte_1 = 0;
    				(LED_matrix_Row_0 & 0x8000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.DC_Green = tempLEDAllData;
    				(LED_matrix_Row_0 & 0x4000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.HF_Green = tempLEDAllData;
    				(LED_matrix_Row_0 & 0x2000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.MF_Green = tempLEDAllData;
    				(LED_matrix_Row_0 & 0x1000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.LF_Green = tempLEDAllData;
    				(LED_matrix_Row_1 & 0x8000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.DC_Yellow = tempLEDAllData;
    				(LED_matrix_Row_1 & 0x4000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.HF_Yellow = tempLEDAllData;
    				(LED_matrix_Row_1 & 0x2000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.MF_Yellow = tempLEDAllData;
    				(LED_matrix_Row_1 & 0x1000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.LF_Yellow = tempLEDAllData;
    				(LED_matrix_Row_2 & 0x8000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.DC_Red = tempLEDAllData;
    				(LED_matrix_Row_2 & 0x4000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.HF_Red = tempLEDAllData;
    				(LED_matrix_Row_2 & 0x2000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.MF_Red = tempLEDAllData;
    				(LED_matrix_Row_2 & 0x1000) ? (tempLEDAllData = 1) : (tempLEDAllData = 0);
    				I2C_Data_Regs.LEDs_Union.LEDs_Bitfield_Union.LF_Red = tempLEDAllData;
                sData[20] = I2C_Data_Regs.LEDs_Union.LED_Byte_1 >> 8;
                sData[21] = I2C_Data_Regs.LEDs_Union.LED_Byte_1;
    
                sData[22] = Trip_Status;
                sData[23] = I2C_Data_Regs.Trip_Status.byteQty;
    				// Update trip status now
    				int tempTripAllData = 0;
    				I2C_Data_Regs.Trip_Status.StatusByte = GMS_Trip ? (tempTripAllData = 1) : (tempTripAllData = 0);
                sData[24] = I2C_Data_Regs.Trip_Status.StatusByte;
    
                sData[25] = Last_State_Change;
                sData[26] = I2C_Data_Regs.Last_State_Change.byteQty;
    				// Update last state change now
    				I2C_Data_Regs.Last_State_Change.StateByte = calVals.lastGMSStateChange;
                sData[27] = I2C_Data_Regs.Last_State_Change.StateByte;
    
                sData[28] = LF_Level;
                sData[29] = I2C_Data_Regs.LF_Level.byteQty;
    				// Update LF level now
    				I2C_Data_Regs.LF_Level.Level_Byte2 = ((lowbpfRMS * 5000) + 10);
                sData[30] = I2C_Data_Regs.LF_Level.Level_Byte1;
                sData[31] = I2C_Data_Regs.LF_Level.Level_Byte2;
    
                sData[32] = LF_Trip_Thresh;
                sData[33] = I2C_Data_Regs.LF_Threshold.byteQty;
    				// Update LF threshold now
    				I2C_Data_Regs.LF_Threshold.Level_Byte2 = ((lfThreshYellow * 5000) + 10);
                sData[34] = I2C_Data_Regs.LF_Threshold.Level_Byte1;
                sData[35] = I2C_Data_Regs.LF_Threshold.Level_Byte2;
    
                sData[36] = MF_Level;
                sData[37] = I2C_Data_Regs.MF_Level.byteQty;
                	// Update MF level now
    				I2C_Data_Regs.MF_Level.Level_Byte2 = ((midbpfRMS * 4215) + 10);
                sData[38] = I2C_Data_Regs.MF_Level.Level_Byte1;
                sData[39] = I2C_Data_Regs.MF_Level.Level_Byte2;
    
                sData[40] = MF_Trip_Thresh;
                sData[41] = I2C_Data_Regs.MF_Threshold.byteQty;
    				// Update MF threshold now
    				I2C_Data_Regs.MF_Threshold.Level_Byte2 = ((mfThreshYellow * 4215) + 10);
                sData[42] = I2C_Data_Regs.MF_Threshold.Level_Byte1;
                sData[43] = I2C_Data_Regs.MF_Threshold.Level_Byte2;
    
                sData[44] = HF_Level;
                sData[45] = I2C_Data_Regs.HF_Level.byteQty;
    				// Update HF level now
    				I2C_Data_Regs.HF_Level.Level_Byte2 = ((highbpfRMS * 4000) + 10);
                sData[46] = I2C_Data_Regs.HF_Level.Level_Byte1;
                sData[47] = I2C_Data_Regs.HF_Level.Level_Byte2;
    
                sData[48] = HF_Trip_Thresh;
                sData[49] = I2C_Data_Regs.HF_Threshold.byteQty;
    				// Update HF threshold now
    				I2C_Data_Regs.HF_Threshold.Level_Byte2 = ((hfThreshYellow * 4000) + 10);
                sData[50] = I2C_Data_Regs.HF_Threshold.Level_Byte1;
                sData[51] = I2C_Data_Regs.HF_Threshold.Level_Byte2;
    
                sData[52] = DC_Level_RMS;
                sData[53] = I2C_Data_Regs.DC_Level.byteQty;
    				// Update DC level now
    				I2C_Data_Regs.DC_Level.Level_Byte2 = ((DClpfRMS * 150) + 0);
                sData[54] = I2C_Data_Regs.DC_Level.Level_Byte1;
                sData[55] = I2C_Data_Regs.DC_Level.Level_Byte2;
    
                sData[56] = DC_Trip_Thresh;
                sData[57] = I2C_Data_Regs.DC_Threshold.byteQty;
    				// Update DC threshold now
    				I2C_Data_Regs.DC_Threshold.Level_Byte2 = ((dcThreshYellow * 150) + 0);
                sData[58] = I2C_Data_Regs.DC_Threshold.Level_Byte1;
                sData[59] = I2C_Data_Regs.DC_Threshold.Level_Byte2;
    
                sData[60] = PP_LF_Level;
                sData[61] = I2C_Data_Regs.PP_LF_Level.byteQty;
    				// Update PP LF level now
    				I2C_Data_Regs.PP_LF_Level.Level_Byte2 = ((lowbpfRMSPP * 656) + 10);
                sData[62] = I2C_Data_Regs.PP_LF_Level.Level_Byte1;
                sData[63] = I2C_Data_Regs.PP_LF_Level.Level_Byte2;
    
                sData[64] = PP_LF_Trip_Thresh;
                sData[65] = I2C_Data_Regs.PP_LF_Threshold.byteQty;
    				// Update PP LF threshold now
    				I2C_Data_Regs.PP_LF_Threshold.Level_Byte2 = ((lfThreshPP * 656) + 10);
                sData[66] = I2C_Data_Regs.PP_LF_Threshold.Level_Byte1;
                sData[67] = I2C_Data_Regs.PP_LF_Threshold.Level_Byte2;
    
                sData[68] = PP_MF_Level;
                sData[69] = I2C_Data_Regs.PP_MF_Level.byteQty;
    				// Update PP MF level now
    				I2C_Data_Regs.PP_MF_Level.Level_Byte2 = ((midbpfRMSPP * 301) + 10);
                sData[70] = I2C_Data_Regs.PP_MF_Level.Level_Byte1;
                sData[71] = I2C_Data_Regs.PP_MF_Level.Level_Byte2;
    
                sData[72] = PP_MF_Trip_Thresh;
                sData[73] = I2C_Data_Regs.PP_MF_Threshold.byteQty;
    				// Update PP MF threshold now
    				I2C_Data_Regs.PP_MF_Threshold.Level_Byte2 = ((mfThreshPP * 301) + 10);
                sData[74] = I2C_Data_Regs.PP_MF_Threshold.Level_Byte1;
                sData[75] = I2C_Data_Regs.PP_MF_Threshold.Level_Byte2;
    
                sData[76] = PP_HF_Level;;
                sData[77] = I2C_Data_Regs.PP_HF_Level.byteQty;
    				// Update PP HF level now
    				I2C_Data_Regs.PP_HF_Level.Level_Byte2 = ((highbpfRMSPP * 225) + 10);
                sData[78] = I2C_Data_Regs.PP_HF_Level.Level_Byte1;
                sData[79] = I2C_Data_Regs.PP_HF_Level.Level_Byte2;
    
                sData[80] = PP_HF_Trip_Thresh;
                sData[81] = I2C_Data_Regs.PP_HF_Threshold.byteQty;
    				// Update PP HF threshold now
    				I2C_Data_Regs.PP_HF_Threshold.Level_Byte2 = ((hfThreshPP * 225) + 10);
                sData[82] = I2C_Data_Regs.PP_HF_Threshold.Level_Byte1;
                sData[83] = I2C_Data_Regs.PP_HF_Threshold.Level_Byte2;
    
                sData[84] = LF_Freq;
                sData[85] = I2C_Data_Regs.LF_Frequency.byteQty;
    				// Update low frequency now
    				I2C_Data_Regs.LF_Frequency.FreqByte1 = (_IQint(freqLow + 0.5)) >> 8;
    				I2C_Data_Regs.LF_Frequency.FreqByte2 = _IQint(freqLow + 0.5);
                sData[86] = I2C_Data_Regs.LF_Frequency.FreqByte1;
                sData[87] = I2C_Data_Regs.LF_Frequency.FreqByte2;
    
                sData[88] = MF_Freq;
                sData[89] = I2C_Data_Regs.MF_Frequency.byteQty;
    				// Update mid frequency now
    				I2C_Data_Regs.MF_Frequency.FreqByte1 = (_IQint(freqMid + 0.5)) >> 8;
    				I2C_Data_Regs.MF_Frequency.FreqByte2 = _IQint(freqMid + 0.5);
                sData[90] = I2C_Data_Regs.MF_Frequency.FreqByte1;
                sData[91] = I2C_Data_Regs.MF_Frequency.FreqByte2;
    
                sData[92] = HF_Freq;
                sData[93] = I2C_Data_Regs.HF_Frequency.byteQty;
    				// Update high frequency now
    				I2C_Data_Regs.HF_Frequency.FreqByte1 = (_IQint(freqHigh + 0.5)) >> 8;
    				I2C_Data_Regs.HF_Frequency.FreqByte2 = _IQint(freqHigh + 0.5);
                sData[94] = I2C_Data_Regs.HF_Frequency.FreqByte1;
                sData[95] = I2C_Data_Regs.HF_Frequency.FreqByte2;
    
    			I2C_Send_Response(sData[1]);
    
                break;
    
            case GM_Test_Engaged: // 0x81
                I2C_Command = 0xff;
    
                I2C_GM_Test_Flag = 1;
    
                sData[0] = GM_Test_Engaged;
                sData[1] = 0x01;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case GM_Test_Disengaged: // 0x82
                I2C_Command = 0xff;
    
                I2C_GM_Test_Flag = 0;
    
                sData[0] = GM_Test_Disengaged;
                sData[1] = 0x00;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case GM_Reset_Engaged: // 0x83
                I2C_Command = 0xff;
    
                I2C_GM_Reset_Flag = 1;
    
                sData[0] = GM_Reset_Engaged;
                sData[1] = 0x01;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case GM_Reset_Disengaged: // 0x84
                I2C_Command = 0xff;
    
                I2C_GM_Reset_Flag = 0;
    
                sData[0] = GM_Reset_Disengaged;
                sData[1] = 0x00;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case GFR_Reset_Engaged: // 0x85
                I2C_Command = 0xff;
    
                I2C_GFR_Reset_Flag = 1;
    
                sData[0] = GFR_Reset_Engaged;
                sData[1] = 0x01;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            case GFR_Reset_Disengaged: // 0x86
                I2C_Command = 0xff;
    
                I2C_GFR_Reset_Flag = 0;
    
                sData[0] = GFR_Reset_Disengaged;
                sData[1] = 0x00;
    
                I2C_Send_Response(sData[1]);
    
                break;
    
            default:
                I2C_Command = 0xff;
                break;
        }
        return I2C_Command;
    }

    Transmit function:

    void I2C_Send_Response(unsigned int byteQty)
    {
        // Setup I2C module modes
        I2caRegs.I2CMDR.bit.IRS         = 0;        // Put I2C module in reset while making changes
        I2caRegs.I2CMDR.bit.TRX         = 1;        // 1 = transmit mode
        I2caRegs.I2CCNT                 = byteQty;  // Set data count (ignored in RM mode)
        I2caRegs.I2CMDR.bit.IRS         = 1;        // I2C module is re-enabled after making changes
    
        for(switchIndex = 0; switchIndex < I2caRegs.I2CCNT; switchIndex++){
            idleCounter1 = 0;
            while(!I2caRegs.I2CSTR.bit.XRDY)
            {
                if(idleCounter1++ >= 30000)		// 30,000 ~ 12.6ms
                								// When the master read happens before data is ready (after the master sends a write)
    											// XRDY is never satisfied.  This algorithm senses this condition and after a time
    											// (~12.6ms) reads the I2CDRR to clear the I2C bus condition.
    											// Extending this delay makes the data transfer more robust, but at the expense of
    											// extending the GMS trip response (during this delay).
    											//
    											//
    											// This is to help unstick the bus when too many writes are issued
                {                               // by master w/o reading. It must be long enough to allow master
    
                    idleCounter1 = 0;           // enough time to download bytes normally.
                    tempByte = I2caRegs.I2CDRR; // It must be short enough to allow quick end to CPU hogging
    
                    // The following resets I2C xmit buffer in case master doesn't pull all data
                    I2caRegs.I2CMDR.bit.IRS         = 0;    // Put I2C module in reset while making changes
                    I2caRegs.I2CCNT                 = 0;    // Set data count to 0 clears xmit buffer
                    I2caRegs.I2CMDR.bit.IRS         = 1;    // I2C module is re-enabled after making changes
                }
    
            }
            I2caRegs.I2CDXR = sData[switchIndex];  // Loads a value into the data xmit buffer, starting the xmit process
        }
    
        idleCounter2 = 0;
        while(I2caRegs.I2CSTR.bit.BB)
        {
            if(idleCounter2++ >= 100000)    // This is to help unstick the bus when xmit buffer empties
            {
                idleCounter2 = 0;
                I2caRegs.I2CDXR = 0xdb;
            }
        }
        // Disable/enable I2C module to change SEND/RECEIVE mode
        I2caRegs.I2CMDR.bit.IRS         = 0;                // Put I2C module in reset while making changes
        I2caRegs.I2CMDR.bit.TRX         = 0;                // Set receive mode
        I2caRegs.I2CMDR.bit.IRS         = 1;                // I2C module is re-enabled after making changes
    }

    Hi Kevin,

    I just received your response to the previous posts, so I'll take a look at that now.  In the meantime, I'll go ahead and send this for reference.

    Thanks for your help,
    robin

  • Hi Kevin,

    Here are responses to your comments:

    Kevin Allen18
    Have you looked at waveforms to understand the state of the bus after an extensive period of time?

    Yes.  After the errant NACK, SDA/SCL are released and remain high until the next I2C transaction.  If no transaction occurs, they stay high forever.  If, after a failure of the large read, I send a request for any of the other bits of info, the system responds normally with the correct data.

    Kevin Allen18
    Does SDA/SCL eventually stop being pulled low before the slave responds to the master device?

    I'm not sure I understand your question, because the analyzer image sent earlier shows the master releases SDA about 30us after the slave ACKs the write command and SCL is released after another 4.5us.  Next, the master pulls SDA low to signal a repeat start condition.  Shortly after the NACK, the master issues a stop condition and the bus normalizes to an idle state.  So, I think the answer to your question is, "Yes, SDA/SCL are released shortly after each master transmission and/or slave response."

    Kevin Allen18
    When running the 'release' configuration are you still able to have a debugger connected?

    Yes, I can still see the inner workings of the processor while in release.  I'm using an Aardvark as the master, so I can't see what's going on inside it.  But I can see the I2C module registers in the 28069.  I can also set breakpoints, etc..  Can you recommend what to look for?

    Kevin Allen18
    Are there any notable differences between your debug and release project versions SW?

    No SW differences.  Same code for both.

    Thanks again,
    robin

  • Hi Robin,

    Sorry it took me a bit to get back to you. Thanks for providing the waveforms and more information, the issue is more clear now.

    Based on your waveforms I think your earlier statement below could be correct:

    Robin Vice said:
    I think what's happening is that the 28069 is taking so long to gather the data to send that the master times out and clears the bus.  If that's it, should I be pulling the clock line low to stretch the clock until the 28069 is ready to send all data?  What's a good way to do that?

    The F2806x does not seem ready to ACK and transmit data back to the master device when it receives the Slave Addr + Read bit. Maybe the I2C registers have not been set to the correct state yet after the initial write command from the master.

    This could be only happening in the Flash config because portions of your code may be executing from Flash instead of RAM, where Flash execution is slower. You can look into copying specific sections of your code from Flash to RAM for this, or the master device would need to re-start the Slave Addr + Read bit until it receives an ACK, meaning the slave is ready to transmit data back.

    Robin Vice said:
    Yes, I can still see the inner workings of the processor while in release.  I'm using an Aardvark as the master, so I can't see what's going on inside it.  But I can see the I2C module registers in the 28069.  I can also set breakpoints, etc..  Can you recommend what to look for?

    Maybe finding out where your code is executing after the master's initial write command and before the Slave Addr + Read bit. Is your F2806x device in a state ready to receive a read command and transmit back?

    Best,

    Kevin

  • Hi Kevin,

    You found it!

    I neglected to move the parser routine, which collects data before transmission, into RAM. 

    One simple #pragma directive and all is well.

    Thanks for your brilliance.

    robin