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.

MSP430F5438A: Erratic behavior of Write/Read functions when using TI USCI in I2C mode. UCB2.

Part Number: MSP430F5438A


In order to narrow the scope of our problem, we have concentrated on one piece of data, a 4-byte float in IEEE format, alarm1Setpoint.  Using the IAR debugger and breakpoints, we originally knew that the Write/Read functions using TI uart in I2C mode worked properly for this float if the functions were called from main.c at startup, or from lcd.c editing from hmi.  Our problem is that if we call these same functions from file HARTCMDS.C following a edit from a HART master, Both write and read functions appear to fail. We have verified that the parameters sent are correct, (a float, and unsigned int numBytes). 

We are writing to/from a Microchip 24FC1025 EEPROM.

 

Further testing has shown that when the write function is called from hart, execution never enters the ISR.  When we call the read function from hart, the write part that sends the address to read from is not sent by the ISR, but the read attempts to use the ISR to read 4 bytes. However, perhaps because the address was not sent, we always read 0xFF for the bytes.

 

I have examined and added #defines to the hart file so that it is identical to main.c , but no help.  We slowed the baud rate to 307,692 because the TI I2C uart has a max of 400k.  No help.

 

Using a logic analyzer, we see that the write protect line is low  during a short burst of clock and data during the failed write, then they end abruptly.  We don’t understand where the clk and data are coming from when execution doesn’t enter the ISR, according to the debugger?

 

Could you please suggest a way forward for us?

 

Thank you for your time,

 

Mike Raines

 

Hoffer Flow Controls, Inc.

252-202-0894

One00100@gmail.com

  • Source code and oscilloscope traces would be helpful.
  • This is the Write function:

    void WriteEepromBlock2(unsigned int address, unsigned char* data, unsigned int numBytes)
    {
    unsigned char* dPtr = data ;
    unsigned char addressH = 0x00; // making local
    unsigned char addressL = 0x00; // making local
    int i = 0; // loop counter
    int j = 0; // loop counter

    // uint calculatedCsum = 0;
    // uchar calculatedCsumL = 0;
    // uchar calculatedCsumH = 0;

    // ==========================================================================================
    // ================== Send bytes to eeprom ===============================================
    // ================== ensure slave address points to block 2 ===============================

    if (UCB2I2CSA != 0x54) // if not block2
    {
    InitializeUcb2Block2();
    } // end if not block 2

    // DelayMs(idelayTimeTiEepromI2c); // Works without this one

    //================= Clear bytesToSend =======================

    for (i=0; i<bytesToSendSize; i++)
    {
    bytesToSend[i] = eraseChar;
    } // end for i

    // =================== load target eeprom address ======================================
    i = 0; // reset loop counter

    addressL = (address & 0xFF);
    addressH = (address >> 8);

    //================= load address and data into bytesToSend ==========================
    bytesToSend[0] = addressH;
    i++;
    bytesToSend[1] = addressL;
    i++;

    for (j=0; j< numBytes; j++) // for each byte
    {
    bytesToSend[i] = *dPtr;
    i++;
    dPtr++;
    } // end for j

    PTxData = (unsigned char*)bytesToSend; // set pointer for isr
    TXByteCtr = i; // 2 byte address,

    // =============== disable write protect and give control to isr =======================

    WPLO; // breakpoint HERE for bytesToSend...
    // DelayMs(5); // Works without this one

    TESTHI;

    UCB2CTL1 |= UCTR + UCTXSTT;

    while(UCB2CTL1 & UCTXSTP); // spin until UCTXSTP bit == 1 (until all bytes have been sent)

    TESTLO;

    DelayMs(1); // Needs this one and needs it before WPHI

    WPHI; // enable write protect


    } // end function void WriteEepromBlock2(unsigned int address, unsigned char* data, numBytes)

    //===================================================================================================
    //===================================================================================================

    This is the function call that works in file lcd.c:
    WriteEepromBlock2(ALBLEVELNV, (unsigned char*) &fcd_FlowCalibrationData.d_AlarmBLevel, FLOAT_SIZE);

    This is the function call in file HARTCMDS.C that doesn't work:
    WriteEepromBlock2( ALBCHOICENV, (uchar*)&tempFloat, FLOAT_SIZE );

    I have logic analyzer (like scope) patterns of success and failures. How do I attach them to this thread??
  • "Use rich formatting", then use "Insert code" or "Insert Media".

  • I have finally solved this damn mystery. I can't believe it took me this long. The problem is that the previous developer set a trap and I fell right into it and didn't see the way out. He did this in 2008 and got away with it until now because he was bitbanging the eeprom I2C interface. I chose to use the TI I2C UART , which uses interrupts . The previous developer committed a cardinal ISR sin: He called ProcessMessage() from inside an ISR. This function goes through about 7 files, finally trying to write and read to eeprom in the middle, before finally returning to the ISR and returning. This tied up the interrupts the TI module needed to write/read, thus causing eeprom write/read to fail ONLY if the functions were called from a certain file. This trail obfuscated the problem and it took me over a month to figure it out. I hope someone can save themselves a lot of heartache by reading this. And I have learned to examine all my ISRs for violations of this rule in every project I do from now.

**Attention** This is a public forum