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.

CCS/UCD3138: Weritten parameters

Part Number: UCD3138

Tool/software: Code Composer Studio

I got answer② to  question① before.
I want to do 2 in answer② . Could you tell me how to do this in detail? With sample code

① Currently using the code of this URL.

      http://www.tij.co.jp/tool/jp/ucd3138fw-psf

Suddenly, the following address value was rewritten to 0xffffffff.

00018880  _pmbus_dcdc_cal_constants             
0001888c  _pmbus_dcdc_cal_nonpaged_constants    
00018890  _pmbus_dcdc_config_constants          
000188d0  _pmbus_dcdc_config_nonpaged_constants 
00018900  _pmbus_checksum                       

Parameters are not rewritten in Fusion digital power studio.

Are there any possible causes?
Can you think of the effects of noise?

②There is a noise related cause that will erase data flash.  In the background loop, there is code like this:

if (erase_segment_counter > 0)
{
       erase_task(); // Handle the DFlash segment erases
}

We have seen cases where system noise and inadequate grounding and filtering of the UCD power supply can cause the processor bit to be changed so that the erase segment counter will be seen as non-zero when it is actually zero.  The end effect of this is that most of the dflash is erased.  

Our recommended way of dealing with this is twofold:

1.  Fix the layout so that the noise level is low enough so that this doesn't happen

2. Put the lock value for the dflash lock in RAM, and have a PMBus command to write to it.  Otherwise, keep it at zero.  That way if a spontaneous data erase or other issue happens in the field, it won't destroy the data.  If you want to actually change the data, for example at production test and calibration, you need to write the lock value.  

Happy Debugging,

  • Here are the directions for changing the code and sending the new PMBus message to write the flash key to RAM and then clear it.  

    1. Create a new variable in RAM:
    EXTERN Uint32 dflash_key;
    2. Create a new pmbus command function:
    int32 pmbus_write_dflash_key(void)
    {
    dflash_key = (pmbus_buffer[2] << 24) + (pmbus_buffer[3] << 16) + (pmbus_buffer[4] << 8) + pmbus_buffer[5];

    return PMBUS_SUCCESS;
    }
    3. Add a case to the pmbus_write_message function to handle writing to dflash_key. I have arbitrarily picked a command code of 0xf3. You will have to pick your own that’s available with your command set:
    case PMBUS_CMD_MFR_SPECIFIC_35: //this translates to command 0xf3
    return pmbus_write_dflash_key();
    4. There are at least 3 spots in the software interrupt function that write or erase the data flash. Case 1, case 3, and case 13 should be the specific cases
    a. All the cases will have a line something like this:
    DecRegs.FLASHILOCK.all = 0x42DC157E; //unlock flash write;
    b. Or this:
    DecRegs.FLASHILOCK.all = DATA_FLASH_INTERLOCK_KEY; //unlock flash write;
    c. Replace the three lines with this:
    DecRegs.FLASHILOCK.all = dflash_key; //unlock flash write;


    Those are the code changes. For writing the calibration data, before you send whatever command writes the data, you will need to send the PMBus command to write to the dflash register. This will be a block write of the correct key, 0X42DC157E.

    The details of the block write are as follows:

    Start
    Address byte with read/write bit cleared
    Command byte – 0xf3 in example code – whatever you select in your code
    Repeated start
    Number of bytes in block – 04 in this case
    42
    DC
    15
    7E
    PEC byte.

    After the write of the data flash, and the erase of the new data flash, you will want to send the command again, only with all zeroes this time, to protect the data flash.

    Note that the data flash write takes about 50 usec per word, and the erase takes 20 msec per page of 32 bytes. Once the erase is started, the PMBus will be active again. So if you don’t wait long enough, some of the erase will not be complete when the dflash_key location is changed. This will make the next write to data flash fail. You need to add more time for overheand, and because timing imposed by a PC is not well controlled. It’s easy for the commands that are sent to the API 1 second apart to get much closer by the time they finally get out.

    You can use the SMBUS debug function in the Device GUI or the Fusion Studio.  In there, it will put in the number of bytes and the checksum.  You just need to put in the device address, the f3 command, and the 42DC157E for the key.  It will automatically insert the number of bytes and the PEC.  

  • Thak you for your reply
    .
    I have another question.
    Why are you using areas (1) and (2)? Isn't it just one?

    Default values are set in area (1). Why is it recorded not only in ROM but also in dflash?
    (1)
    00018880  _pmbus_dcdc_cal_constants             
    0001888c  _pmbus_dcdc_cal_nonpaged_constants    
    00018890  _pmbus_dcdc_config_constants          
    000188d0  _pmbus_dcdc_config_nonpaged_constants 
    00018900  _pmbus_checksum
    (2)
    000189a0  _pmbus_dcdc_cal_constants_b              
    000189ac  _pmbus_dcdc_cal_nonpaged_constants_b     
    000189b0  _pmbus_dcdc_config_constants_b           
    000188f0  _pmbus_dcdc_config_nonpaged_constants_b  
    00018a20  _pmbus_checksum_b                       
  • There are two copies of the data because there can always be a power failure during the write to the data flash.  First we write the new data, then we erase the old data.  If we just had a single data area, and erased it and then wrote the new values a power failure during the process would leave us without viable configuration data.  

  • Thak you for your reply
    .
    I have another question.
     Currently using the code of this URL.

          https://www.tij.co.jp/tool/jp/UCD3138FW-PSFB

    The following code is in flash.c.

    if ((checksum! = pmbus_checksum) && (pmbus_checksum! = 0x87654321))

    Can you tell me the role of the if statement because I want to check what this if statement is determining?

    Can this if statement become true?

    void look_for_interrupted_dflash_erase(void)
    {
     volatile Uint32 bytes_to_erase, checksum, checksum_b,blank_checksum;;
     bytes_to_erase = ((Uint8*)&pmbus_checksum - (Uint8*)&filter0_pmbus_regs_constants);
     blank_checksum = 0xff * bytes_to_erase;
     checksum = calculate_dflash_checksum((Uint8*)&filter0_pmbus_regs_constants,
      (Uint8*)&pmbus_checksum);
     if(checksum != blank_checksum)
     {
      if((checksum!=pmbus_checksum)&&(pmbus_checksum!=0x87654321))
      { //erase BANK A
       start_erase_task((void*)&filter0_pmbus_regs_constants, (bytes_to_erase + 4)); 
       return;
      }

  • Please start a new form for any new questions.  That makes it possible for other people to search for the answers.

    I'm not sure what your question is, so I'll just describe the whole thing.

    The data flash block could be in three states:

    1, Totally erased - blank

    2. Valid data

    3. Partially erased

    To tell what's happening, first we calculate what the checksum would be for an erased (all FFs) data block.  That's blank_checksum

    Then we calculate the checksum for the data flash.

    Then we compare the stored checksum with the blank checksum - if this is valid, we are OK, it's already erased.

    We do not have support for putting a data flash checksum in at compile time, or in the downloader, so we start with the 87654321 value in the checksum to validate that at least data has been downloaded.  

    So the next if statement checks for a valid checksum, or the 876... value.  If the stored checksum matches wither of those, then the data is probably valid.  If none of those match, then the data block is partially erased, or corrupted, so we need to erase it.  

    That's how the code works.