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.

UCD3138: How to define the communication address variable (ID) in DFLASH

Part Number: UCD3138

Hi Guys:

         Can you tell me the following answer?

      1. How to define the communication address variable (ID) in DFLASH;
      2. How to save RAM communication address variable (ID) to DFLASH;
      3. How to update the communication address variable (ID) in DFLASH to RAM call.

  • I'm not sure which variable you are mentioning, as there are several IDs, so I'll just provide general guidelines.

    There are several steps you need to do:

    1. define a data flash area in which to store the data

    2. Define a RAM variable in which to store the data

    3.  Make a PMBus command to write the data to RAM

    4.  Make or modify a PMBus command to read the data

    5.  Implement or modify a PMBus command to copy the RAM data into dflash

    6. Implement or modify a PMBus command to copy the dflash data into RAM, which can also be invoked at startup

    I don't think that any of our EVM codes support any writing of text values to the data flash, but they all support writing extensive filter and system settings.

    You can look at all that code for examples of how to handle the whole process.

    For example, let's take the LLC EVM code at http://www.ti.com/tool/UCD3138FW_LLC

    For step one, you need to look at the cyclone.cmd file.  You can find it in the project explorer in CCS under Devices/UCD3138/Linker.

    Note the Sections declarations that look like this:

    .CONFIG : {} > (DFLASH align(32))
    .CONFIG_B : {} > (DFLASH align(32))

     These are telling the linker to make Sections in data flash for storing things.  The Align 32 is to make sure that it uses full 32 byte pages.  The data flash erases 32 bytes at a tlime.  We make 2 sections so that we always have a valid one.  When we change data, we write it to the empty version before erasing the old one.  

    Next go to constants.c, which is in the main folder in project explorer.

    There are lots of statements like this:

    #pragma DATA_SECTION(filter0_pmbus_regs_constants, ".CONFIG")
    volatile const FILTER_PMBUS_REGS filter0_pmbus_regs_constants = DEFAULT_FILTER_0_PMBUS_REGS;

    #pragma DATA_SECTION(filter0_pmbus_regs_constants_b, ".CONFIG_B")
    volatile const FILTER_PMBUS_REGS filter0_pmbus_regs_constants_b;

    These assign values to the data flash at compile time - default values, if you will.  They have the apparently conflicting description of volatile constants, because that is what they really are.  If we don't put the volatile tag in there, sometimes the compiler will optimize out the data flash access entirely.

    If you use the search tools, you will find that the structures and constants are defined in pmbus_topology.h.

    With all of these steps above, you will define a data flash area and put the data in it.  I'm going to do multiple replies so I don't suffer too much if I have an interruption or a crash.  

  •  

    I forgot to mention pmbus_constants.h  In this file the constants are defined as externs.  It needs to be included in all files that use the stuff stored in data flash, except for constants.c, where the constants are actually initialized.  Note that there are lots of ID strings defined here as well, but all of these, including the device ID string are actually in program flash instead.  The Device ID string is in a specific program flash location, but this is a historical relic, it doesn't actually have to be there.  You can move it to data flash if you want to.  

    Step 2 is to define a RAM variable in which to store the data. This is done in pmbus_topology.h.  For example here:

    EXTERN PMBUS_DCDC_CONFIG pmbus_dcdc_config[DCDC_PAGE_NUMS];
    EXTERN PMBUS_DCDC_CONFIG pmbus_dcdc_config_translated[DCDC_PAGE_NUMS];
    EXTERN PMBUS_DCDC_CAL pmbus_dcdc_cal[DCDC_PAGE_NUMS];

    EXTERN PMBUS_DCDC_CONFIG_NONPAGED pmbus_dcdc_config_nonpaged;
    EXTERN PMBUS_DCDC_CONFIG_NONPAGED pmbus_dcdc_config_nonpaged_translated;
    EXTERN PMBUS_DCDC_CAL_NONPAGED pmbus_dcdc_cal_nonpaged;
    EXTERN Uint16 dcdc_temperature_1, dcdc_temperature_2, dcdc_temperature_3, dcdc_temperature_4;


    If you search through for EXTERN, you will find others as well.  There is a definition of variables for each struct and variable stored in data flash.  

    For step 3, there are lots of PMBus commands to store the data into RAM.  A really simple example is in pmbus_topology.c:

    inline Uint8 pmbus_write_ton_rise(void)
    {
    pmbus_dcdc_config[0].ton_rise = pmbus_buffer[1] + (pmbus_buffer[2] << 8);
    configure_vout_timing();

    return PMBUS_SUCCESS;
    }

    You can see that the value is just copied into the RAM.  You just need to do the same thing with your string into the RAM.  Probably with some overflow checking in case the string is too long.  There is a variable - pmbus_number_of_bytes, that will give you how many bytes are in the PMBus buffer.  The first byte will be the command, the second byte will be the number of bytes in the block, which will be the string, and the last byte will be the checksum.  So you should use the second byte as the number of bytes in the string.  pmbus_buffer[1].

    You obviously don't need something like configure_vout_timing, since the string has no effect on the system setup.  

  • Step 4 is easy, because there are lots of commands to read strings - For instance, if you look in the drivers folder and open pmbus_common.c, you will find this:

    inline Uint8 pmbus_read_mfr_id(void)
    {
    send_string(mfr_id, (Uint8) MFR_ID_LENGTH);
    return PMBUS_SUCCESS;
    }

    We use the string length as well, because we haven't bothered to use the null character that C is doubtless putting at the end of the string.  I guess this means that you will need to store the strings with length information - another variable to store in data flash.  Or you could use the null character method.

    All you need to do is to make mfr_id into a RAM variable instead of the flash constant it is now.  And make the length a RAM variable as well.

    I should mention how to make PMBus commands as well.  With the version of the PMBus firmware used in the LLC, you need to make some #defines.

    Look at the code around read_mfr_id.  Note how the read/write function uses a parameter to decide whether to call a read or a write function.  So you need to make a read/write function, and then have it either call the a special function, or like the write works now for this function, an invalid function.  

    So if you wanted to make a write to mfr_id, you could just define the function and call it from the read write mfr_id function.  

    To see what you need to do to add a new function, do a global file search on the name of the read/write function.  You'll see this in pmbus_topology.h:

    Uint8 pmbus_read_write_mfr_id(Uint8 pmbus_read);
    #define PMBUS_CMD_99_FUNCTION_POINTER pmbus_read_write_mfr_id
    #define PMBUS_CMD_99_QUERY (QUERY_COMMAND_SUPPORTED + QUERY_READ_SUPPORTED + QUERY_NON_NUMERIC)

    There's some fancy table generation firmware using #defines, and this tells it what function to call, and how to respond to a query.  If you look at the definitions of the QUERY constants, as well as the QUERY command documenation in the PMBus manual, this will be clear.  

    There is one more thing you need to add to add a new command.  If you search for 99 in the same file, you will also find this:

    #define PMBUS_CMD_96_ENABLE (0)
    #define PMBUS_CMD_97_ENABLE (0)
    #define PMBUS_CMD_98_ENABLE (1) //done
    #define PMBUS_CMD_99_ENABLE (1)
    #define PMBUS_CMD_9A_ENABLE (1)

    The enable is already set to a 1, because this command is already enabled.  If you want to make a new command that's currently unused, you will need to change the enable to a 1 in this table.  

  • Number 5 is the most fun one - writing the data to the data flash.  

    It's really complicated, because it involves finding which of the two data flash areas is erased, writing the data to the data flash, complete with checksum at the end, and then starting the erase of the old data from the other flash area.  

    You can see most of it from the pmbus_write_store_default_all PMBus command.  

    There is a little call to check if data flash erase is complete in the initialization at restart, and a data flash erase state machine called in main that completes the erase.

    You can either use this code and add the ID strings you want to what is handled here, or you can duplicate it if you want a different command specifically for storing the ID.

    Number 6 is somewhat simpler, since it doesn't involve writing, just reading.  You can see it in the pmbus_write_restore_default_all command.  Of course you don't need all that fancy translation and copying for registers for your ID strings.  Just copy into RAM, and you're done.  Note that restore_default_all is also called in the initialization at restart.  

  • Hi Lan Bower;

             Still can't write flash; IC is UCD3138RHAR;

    1、in the program to pmbus_dcdc_config_nonpaged.vin_ov_fault_limit can be assigned, but call pmbus_write_store_default_all();  Still can't write flash;The program I adopted was ucd3138hsfbevm-029 version: E1;

     

    2、Write DFLASH through the following program, the chip locks:

        write_address(0x00018954, rs485id);

     

    void write_address(int * rs485address, int data)

    {

     

        while(DecRegs.DFLASHCTRL.bit.BUSY != 0)

           {

               ; //do nothing while busy erasing DFlash

           }

        DecRegs.MFBALR1.bit.RONLY = 0;

        DecRegs.FLASHILOCK.all = 0x42DC157E;

     

        * rs485address = data ;

     

        DecRegs.MFBALR1.bit.RONLY = 1;

     

        while(DecRegs.DFLASHCTRL.bit.BUSY != 0)

           {

               ; //WAIT

           }

    }

     

     

    3、When the following warning appears after downloading the x0 file,  how to correct it:

    2019/9/29 14:11:24 Looking for device in program mode ...

    2019/9/29 14:11:25 DEVICE_ID 'UCD3100ISO1|0.0.11.0105|141009' is not valid; mapping to UCD3100ISO1

    2019/9/29 14:11:25 DEVICE_ID 'UCD3100ISO1|0.0.11.0105|141009' is not valid; mapping to UCD3100ISO1

    2019/9/29 14:11:25 Found DC-DC  Firmware v0.0.11.105 @ Address 88d in program mode

     


  • Hi Lan Bower;

             Still can't write flash; IC is UCD3138RHAR;

    1、in the program to pmbus_dcdc_config_nonpaged.vin_ov_fault_limit can be assigned, but call pmbus_write_store_default_all();  Still can't write flash;The program I adopted was ucd3138hsfbevm-029 version: E1;

     

    2、Write DFLASH through the following program, the chip locks:

        write_address(0x00018954, rs485id);

     

    void write_address(int * rs485address, int data)

    {

     

        while(DecRegs.DFLASHCTRL.bit.BUSY != 0)

           {

               ; //do nothing while busy erasing DFlash

           }

        DecRegs.MFBALR1.bit.RONLY = 0;

        DecRegs.FLASHILOCK.all = 0x42DC157E;

     

        * rs485address = data ;

     

        DecRegs.MFBALR1.bit.RONLY = 1;

     

        while(DecRegs.DFLASHCTRL.bit.BUSY != 0)

           {

               ; //WAIT

           }

    }

     

     

    3、When the following warning appears after downloading the x0 file,  how to correct it:

    2019/9/29 14:11:24 Looking for device in program mode ...

    2019/9/29 14:11:25 DEVICE_ID 'UCD3100ISO1|0.0.11.0105|141009' is not valid; mapping to UCD3100ISO1

    2019/9/29 14:11:25 DEVICE_ID 'UCD3100ISO1|0.0.11.0105|141009' is not valid; mapping to UCD3100ISO1

    2019/9/29 14:11:25 Found DC-DC  Firmware v0.0.11.105 @ Address 88d in program mode

  • I can't comment on some of it, because I don't know what is at 0x18954.  I notice that you don't have any erase set up.  

    If it's in the middle of the config block, you will end up with an incorrect checksum, which could explain some issues.

    You need to use the data flash write function in the software interrupt.  You can't just write your own function and call it, because the main program is set up in user mode, which doesn't have permission to write to the flash control register.  

    You are changing the Ronly in MFBALR1, which is the memory fine base address register for the program flash, you need to use MFBALR2, which is for the data flash.

    Once in a while, depending on versions and settings, the compiler will try to access the DecRegs as a byte or half word, which causes problems.  It's better to do something like this:  

    DecRegs.MFBALR2.all &= ~(1<<1); // clear RONLY bit

  • Sorry I'm slow responding, I was on vacation last week.