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.

TPS65982 bringup via I2C

Other Parts Discussed in Thread: TPS65982, TPS65982-EVM

I'm working on a USB Type C solution. A TPS65982, a W25Q80 flash connected via SPI, a host microprocessor connected via I2C1. The flash is initially empty. How to get the firmware/configuration into the flash? How to do the bringup of the flash?

I've started with a TPS65982-EVM. Connected it via I2C to the microcontroller. Ported the relevant python script (flash_update_region_0/1.py) to our host system. Update works like a charm via I2C 4CC commands. Can update low or high region. Can destroy one region. Can boot from the other. Can repair the first. Good solution for updates.

Now I've erased the flash. TPS65982 boots, scans the flash and reports via register 0x2D that it can not boot correctly (flash attached, tries region 0 and 1 but fails with CRC error). Reading the flash (FLrd) returns bogus zeros only. Writing/updating the flash (FLwd) does no longer yield the expected results. Reading register 0x03 gives 'BOOT'. So back to my original question: how to do bringup with an empty flash? Are there alternatives to SPI? (maybe SWD?)

Regards, Michael

  • Michael,

    Great line of questioning!

    The SPI Flash IC must either be pre-programmed before soldering it down onto a board in production, or a connection to the required SPI Flash IC pins must be made available (SPI_CLK, SPI_SSZ, SPI_MISO, SPI_MOSI, VCC & GND) with a header. A lot of people will use a low-profile 6-pin header and have a latchable wire go over to an external PCB with a larger header connection for SPI Flash programming HW to connect.

    In a true production environment, the DediProg SF600 is often used because you can program up to 8 Flash chips at a time. For the most part, we just use the TotalPhase Aardvark to recover the Flash IC when it is completely corrupted or empty. When the Aardvark is used, VIN_3V3 or VBUS must be provided to the TPS65982 to generate LDO_3V3 and power the flash, while the DediProg provides VCC to the Flash when the TPS65982 is un-powered. Some customers prefer to use a socket on the PCB for the SPI Flash so they can swap them out faster to re-program.

    Since you've already used the .py Python files to program Region 0/1 separately, you should try the attached .py script that identifies the active Region and updates both Regions in sequence for a Full I2C FW Flash update. This is a full FW update of both Region0 & 1 followed by a 'GAID' command (HW reset) to re-boot the TPS65982. This .py script can be made even more robust by flipping the pointer and inserting a 'GAID' command in the middle of the sequence. Feel free to play around with it and follow-up with any questions you have.

    flash_update_fullFW_I2C.py
    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    #!/bin/env python
    #==========================================================================
    # (c) 2015 TI
    #--------------------------------------------------------------------------
    # Redistribution and use of this file in source and binary forms, with
    # or without modification, are permitted.
    #
    # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    # POSSIBILITY OF SUCH DAMAGE.
    #==========================================================================
    #==========================================================================
    # IMPORTS
    #==========================================================================
    import sys
    import time
    from hi_functions import *
    from intelhex import IntelHex
    import struct
    from hw_interface import *
    #==========================================================================
    # CONSTANTS
    #==========================================================================
    PAGE_SIZE = 64
    handle = hw_interface(config.DEVICE_I2C_ADDR, config.HW_INTERFACE)
    # header values
    Ace_ID_Value = 0xACE00001
    # Global Variables
    failure = 1
    error_flag = 0
    # Local Variables
    tDelay = 5
    #==========================================================================
    # Functions
    #==========================================================================
    # Function to bit-reverse a byte array in place
    # '{:08b}'.format(x)converts a byte to a bit string, 8 bits, leading 0s
    # slice operator bitstr[start:end:step] reverses the bit string when step -1
    # int(bitstr,2) converts bit string (base 2) back to an integer
    # write back to the same array
    def bit_rev(data):
    index = 0
    for x in data:
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  • Thanks for your clarification. I was afraid this would be your answer. I suggest a datasheet update to clearly make a distinction between bringup of flash and update.

    Thanks also for your Python suggestion, this will be handy during update.

    Regards, Michael
  • Michael,

    Thank you for your feedback on the datasheet. Since the TPS65982 is a pretty even split between HW & FW capabilities, we try to make a clear distinction on what goes in the datasheet (HW) and what goes into the TPS6598X FW User's Guide (FW). Here, I could see this change fitting in either document well, or simply fitting the "bring-up" vs. "upgrade" distinction into the Intro of an App Note.

    I hope the Python script works well for you. I will be posting an App Note regarding C-code Examples for FW update in the near future, so I'll post a link here when it's published.
  • Michael,

    Please find my latest e2e Post here on this subject: e2e.ti.com/.../512830
    This is a Python script that is updated even further, or "enhanced", to update Region 1 (or 0), then Reset the TPS65982 to load the new FW, then update Region 0 (or 1) and Reset again.

    In the ideal flow (Region 0 is valid and running before the FW Update), after updating Region 1 the Flash image pointers are flipped and the new FW version can be confirmed as valid before moving on to update Region 0.