TI E2E Community (Beta)
Welcome to the TI E2E (Engineer-to-Engineer) Community! We invite you to freely and openly interact with your peer Engineers, TI Engineers, and other experts in order to ask questions, share knowledge, explore ideas, and help solve problems.
More Search Options

TUSB3410 and I2C

rated by 0 users
Not Answered This post has 0 verified answers | 11 Replies | 2 Followers

Not Ranked
8 Posts
Community Member
Peter Hull posted on 19 Mar 2009 10:21 AM

I want to write to an EEPROM via the I2C bus and I'm following the steps in the data manual (SLLS519G). I'm finding that I need to put a delay between successive page writes, so the sequence is: send address, send 32 bytes, delay, send address, send 32 bytes ...

I'm waiting for TXE every time I set I2CDAO, as in the data manual.

If I don't delay only the first 32 bytes are written and the rest aren't.

Am I missing something or should there be a delay and if so how long (or does it depend on the EEPROM used?)

All Replies

Not Ranked
8 Posts
Community Member

The EEPROM manual (it's an ST M24C64) says to set the device address, and then poll for ACK on the i2c bus (SDA low); if there's no ACK then the E2 is not ready, so repeat the start/device address sequence until it is. 

So, how do I check if there's an ACK or not using the TUSB's registers?

Not Ranked
8 Posts
Community Member

Well, it doesn't seem too busy in here. Maybe if I just try the write several times with a short delay?

 int retry = 3;
while ((write(...) != NO_ERROR) && (--retry > 0))
{
delay();
}

 What do you think?

 Pete

Top 100 Contributor
61 Posts
Texas Instruments Employee

The page-write operation is initiated in the same way as byte write, with the exception that a stop condition is not generated after the first EPROM [DATA] is transmitted. The following describes the sequence of writing 32 bytes in page mode.

Device Address + EPROM [High Byte]

The MCU clears bit 0 (SWR) in the I2CSTA register. This forces the I2C controller to not generate a stop condition after the contents of the I2CDAO register are transmitted.

The MCU writes the device address (bit 0 (R/W) = 0) to the I2CADR register (write operation).

The MCU writes the high byte of the EEPROM address into the I2CDAO register

Bit 3 (TXE) in the I2CSTA register is cleared (indicating busy).

The contents of the I2CADR register are transmitted to the device (preceded by start condition on SDA).

The contents of the I2CDAO register are transmitted to the device (EEPROM address).

Bit 3 (TXE) in the I2CSTA register is set and interrupts the MCU, indicating that the I2CDAO register contents have been transmitted.

EPROM [Low Byte]

The MCU writes the low byte of the EEPROM address into the I2CDAO register.

Bit 3 (TXE) in the I2CSTA register is cleared (indicates busy).

The contents of the I2CDAO register are transmitted to the device (EEPROM address).

Bit 3 (TXE) in the I2CSTA register is set and interrupts the MCU, indicating that the I2CDAO register contents have been transmitted.

EPROM [DATA]—31 Bytes

The data to be written to the EEPROM are written by the MCU into the I2CDAO register.

Bit 3 (TXE) in the I2CSTA register is cleared (indicates busy).

The contents of the I2CDAO register are transmitted to the device (EEPROM data).

Bit 3 (TXE) in the I2CSTA register is set and interrupts the MCU, indicating that the I2CDAO register contents have been transmitted.

This operation repeats 31 times.

EPROM [DATA]—Last Byte

The MCU sets bit 0 (SWR) in the I2CSTA register. This forces the I2C controller to generate a stop condition after the contents of the I2CDAO register are transmitted.

The MCU writes the last date byte to be written to the EEPROM, into the I2CDAO register.

Bit 3 (TXE) in the I2CSTA register is cleared (indicates busy).

The contents of the I2CDAO register are transmitted to EEPROM (EEPROM data).

Bit 3 (TXE) in the I2CSTA register is set and interrupts the MCU, indicating that the I2CDAO register contents have been transmitted.

The I2C controller generates a stop condition after the contents of the I2CDAO register are transmitted.

Not Ranked
8 Posts
Community Member

Thanks for your reply. It looks like you've pasted me a section from the data manual that I referred to in my first post. To clarify what I'm doing: 

WORD index = 0;
BYTE err = NO_ERROR;
while ((err == NO_ERROR) && (index < SIZE))
{
 err = i2cWrite(0, index, 32, &buffer[index]);
 index += 32;
}

Where i2cWrite is a function taken directly from the TI Bootcode Source Listing SLLC139. It writes the first 32 byte chunk but not subsequent ones. The manual for the EEPROM I'm using says that if it is not ready to write, it will not acknowledge the device select. So my question is: can I detect when the device select is not acknowledged or do I just retry the i2cWrite a number of times with pauses (assuming that if the function fails, say,  5 times in a row there's a hardware error).

Looking at the steps you posted:

The MCU writes the device address (bit 0 (R/W) = 0) to the I2CADR register (write operation).

The MCU writes the high byte of the EEPROM address into the I2CDAO register

Bit 3 (TXE) in the I2CSTA register is cleared (indicating busy).

The procedure could fail when I2CADR is set, but there's no step for checking that. Or is the address not transmitted until I2CDAO is written?

Pete


 

Top 100 Contributor
61 Posts
Texas Instruments Employee

The following is a code portion taken from our EEPROM burner's FW source code.

----------------------------------

BYTE i2cWrite(BYTE bDeviceAddress, WORD wAddress, WORD wNumber, PBYTE pbDataArray)
{
    BYTE bTemp,bHiAddress;
   
    bI2CSTA &= ~(I2CSTA_SRD | I2CSTA_SWR);  // clear SRD and SWR bit

    // If error, return a value other than zero.
    if(wNumber == 0x00) return NO_ERROR;

    if(bDeviceCategory == I2C_CATEGORY_1){
        // cat 1
        bI2CADR = (BYTE)(wAddress << 1);
    }else{
        // cat 2 or 3
        bTemp    = bDeviceAddress & MASK_I2C_DEVICE_ADDRESS;    // write device address and RW=0
        bTemp    = bTemp << 1;                          
        bTemp   |= BIT_I2C_DEVICE_TYPE_MEMORY;                  // add control code

        // check if data address is higher than 0xff in cat 2 device
        if((bDeviceCategory == I2C_CATEGORY_2) && (wAddress > 0x00ff)){
            bHiAddress  = (BYTE)(wAddress >> 8) & MASK_I2C_DEVICE_ADDRESS;
            bHiAddress  = bHiAddress << 1;
            bTemp      |= bHiAddress;
        }
        bI2CADR = bTemp;                            // write out device address

        if(bDeviceCategory == I2C_CATEGORY_3){
            bI2CDAO  =  (BYTE)(wAddress >> 8);      // write out high byte of address
            if(i2cWaitForWrite() != NO_ERROR) return ERROR;     // bus error
        }

        bI2CDAO  =  (BYTE)(wAddress & 0xff);        // write out low byte of address
        if(i2cWaitForWrite() != NO_ERROR) return ERROR;         // bus error
    }

    // SRD should be cleared.
    while(wNumber > 1){
        bI2CDAO = *pbDataArray++;
        if(i2cWaitForWrite() != NO_ERROR) return ERROR;          // bus error
        wNumber--;
    }

    // write the last byte
    bI2CSTA |= I2CSTA_SWR;                          // set SWR bit
    bI2CDAO  = *pbDataArray;                        // write out the data

    if(i2cWaitForWrite() != NO_ERROR) return ERROR;             // bus error
    return NO_ERROR;
}

-------------------------

I can notice from there that some delays are being inserted (i2cWaitForWrite), and SDR bit is being cleared... Let me know if it's useful.

Not Ranked
8 Posts
Community Member

Right, the code portion you've quoted is exactly what I meant by "... i2cWrite is a function taken directly from the TI Bootcode Source Listing SLLC139"

I've got a category 3 device, so looking at the code for i2cWrite, it does this:

  1. write out device address
  2. write out high byte of the address
  3. wait
  4. write out low byte of the address
  5. wait
  6. write out first data byte
  7. wait
  8. write out second byte...etc etc

You will notice there's no wait between steps 1 & 2. i2cWaitForWrite is not a time delay, it polls the TXE bit which indicates that the data has been sent. My EEPROM manual says that if it is not ready to receive the next command, it does not acknowledge the device address byte. So how can I check if the device is ready using the TUSB's controller. What I want is

  1. write out device address
  2. If not acknowledged go to step 1
  3. write out high byte of the address
  4. wait
  5. write out low byte of the address
  6. wait
  7. write out first data byte
  8. wait
  9. write out second byte...etc etc

Do you see what I mean?

Top 100 Contributor
61 Posts
Texas Instruments Employee

In case of the TUSB3410 device accesses a Cat 3 device like this: Two bytes of data are written to addresses i and i+1. Two bytes of data address, A15 to A0, are sent out before the data bytes (Take a look at the attached Write-I2C-Cat3.jpg).

Note: There are certain restrictions to the types of EEPROM devices that can be used. I2C EEPROM devices available on the market can be grouped by the way they are addressed on the I2C bus. It is necessary to consider this when selecting a device for use with a TI USB controller, since some types are not supported with some controllers, and in some cases the device address may need to be configured differently depending on the type.

Not Ranked
8 Posts
Community Member

I appreciate the time you're spending to help me, and I think we're getting to the heart of it now. I have code that I'm confident will correctly write data to the EEPROM, and I am confident because the TI docs are clear, and also because I based my code on the TI bootcode example. The problem is that if I do writing in a loop, the first one will succeed and the next write will fail. I know the reason for this - to quote the EEPROM manual:

During the internal Write cycle, the device disconnects itself from the bus, and writes a copy of the data from its internal latches to the memory cells. The maximum Write time (tw) is shown in Table 17 and Table 18 , but the typical time is shorter. To make use of this, a polling sequence can be used by the bus master. The sequence, as shown in Figure 10 , is:

1. Initial condition: a Write cycle is in progress.

2. Step 1: the bus master issues a Start condition followed by a device select code (the first byte of the new instruction).

3. Step 2: if the device is busy with the internal Write cycle, no Ack will be returned and the bus master goes back to Step 1. If the device has terminated the internal Write cycle, it responds with an Ack, indicating that the device is ready to receive the second part of the instruction (the first byte of this instruction having been sent during Step 1).

I have attached their figure 10 (with my annotations in red) which shows how they think it should be done. My question is, how do I do the part marked ???, detect when the EEPROM is busy? By the way the EEPROM is one that is supported by the TUSB (it is listed in the TUSB burner manual), so no worries there.

Peter

Top 100 Contributor
61 Posts
Texas Instruments Employee

How about this part of the M24C64 EEPROM’s datasheet?

 

4.3 Acknowledge bit (ACK): The acknowledge bit is used to indicate a successful byte transfer. The bus transmitter, whether it be bus master or slave device, releases Serial Data (SDA) after sending eight bits of data. During the 9th clock pulse period, the receiver pulls Serial Data (SDA) Low to acknowledge the receipt of the eight data bits.

 

If you can somehow write one byte data transfers, one after the other you could monitor each ACK. This is just to make some experimentation. Please let me know if it makes sense.

Not Ranked
8 Posts
Community Member

Actually I have resorted to putting in a delay for now. But..., what I would like to know is - how do I test the acknowledge bit with the TUSB?

Thanks for your help.

Top 100 Contributor
61 Posts
Texas Instruments Employee

I'm not sure if any bits in I2CSTA (I2C Status and Control Register) can help you out to test the ack in the E2.

Regards,

Ismael

Page 1 of 1 (12 items) |

ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". TI AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY TI. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM TI.

Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.