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.

TMS320F28379D: Flashing address not on 4 word, 8 word boundaries

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE

I have a situation where I have to flash 6 words starting at 0x980FE.

What are the rules for flashing memory not on a 4-word or 8-word boundary?

Can you straddle two 128-bit boundaries? If not, how should this be handled?

And what about straddling a sector, e.g.  0x9FFFE to 0xA0004? How should this be handled?

thanks and happy new year!

  • Tonyo,

    Please search for "How many bits can be programmed at a time using Fapi_issueProgrammingCommand()?" in Flash API wiki at processors.wiki.ti.com/.../C2000_Flash_FAQ .

    Once you read the wiki question that above, let me know if you have further questions.

    Whether it is sector edge or not, program command can work only with in a 128-bit boundary at a time.

    Thanks and regards,
    Vamsi
  • I have a case where addresses ending in 0xFE do not seem to program.
    Instead, I get an error 0x30 from Fapi_getFsmStatus().
    I dumped the flash before and after programming, as well as the flash data below:
    FLASHPROG_write: program addr=0x000981FE len=2 (0x0002)
    flash_check: (0x000981FE): FFFFFFFF != 768AFEF9
    flash_check: 000981FE[0000](0x000981FE): FFFF != FEF9
    flash_check: 000981FE[0001](0x000981FF): FFFF != 768A
    flash_check: 2 errors
    (2 (0002) words) Data:
    [0001680A] FEF9 768A
    (2 (0002) words) Before programming:
    [0000D900] FFFF FFFF
    (2 (0002) words) After programming:
    [000981FE] FFFF FFFF
    FLASHPROG_write: WRITE ERROR status:48 (0x00000030) addr:0x000981FE len:0x0002
    The programming code is:
        uint16_t i = 0; // index of data to flash
        uint32_t addr = address32; // pointer to flash memory
        Fapi_StatusType status = Fapi_Status_Success; // return status
        int32_t word_count = lenWords; // # words to flash from data to addr
        {    // copy erased area for reference later
            uint16_t *p = (uint16_t *) address32;
            int n=0; for(n=0; n<256; n++) flash_buf[n] = *p++;
        }
        while(word_count > 0)
        {
            uint16_t blk_len = word_count;
            if(blk_len > 8) blk_len = 8;                    // pin blk_len to max size of block
            if(addr & 0x07) blk_len = 8 - (addr & 0x07);    // not on 8-word boundary, adjust block size
            debug_printf("FLASHPROG_write: program addr=0x%X len=%u (0x%x)\n", addr, blk_len, blk_len);
            status = Fapi_issueProgrammingCommand((uint32_t *)addr, &data[i], blk_len, 0, 0, Fapi_AutoEccGeneration);
            if(status == Fapi_Status_Success)
            {
                while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy) asm(" NOP");  // wait for state machine to finish
                Fapi_FlashStatusType tmp_status = Fapi_getFsmStatus(); // status at end of flash operation
                int error_count = flash_check((uint16_t *)addr, &data[i], blk_len); // compare to original data
                if(error_count) // dump data, erased flash, programmed flash
                {
                    debug_dump("Data:", &data[i], blk_len);
                    debug_dump("Before programming:", &flash_buf[i], blk_len);
                    debug_dump("After programming:", (uint16_t *)addr, blk_len);
                }
                if(tmp_status != 0 || error_count)
                {
                    debug_printf("FLASHPROG_write: WRITE ERROR status:%n (0x%X) addr:0x%X len:0x%x\n", tmp_status, tmp_status, address32, blk_len);
                    status = Fapi_Error_Fail;
                    break;
                }
            }
            else
            {
                break;
            }
            addr += blk_len;         // move to next block
            i += blk_len;
            word_count -= blk_len;
        }
    flash_check() uses both a call to Fapi_doVerify() as well as a word-by-word check:
    __attribute__((ramfunc))
    uint16_t  flash_check(uint16_t *programmed, uint16_t *data, uint16_t len)
    {
        int error_count=0;
        Fapi_FlashStatusWordType oFlashStatusWord;
        Fapi_StatusType oReturnCheck = Fapi_doVerify((uint32_t *)programmed, len/2, (uint32_t *)data, &oFlashStatusWord);
        if(oReturnCheck != Fapi_Status_Success)
        {
            debug_printf("flash_check: (0x%X): %X != %X\n", oFlashStatusWord.au32StatusWord[0], oFlashStatusWord.au32StatusWord[1], oFlashStatusWord.au32StatusWord[2]);
        }
        int i;
        for(i=0; i<len; i++)
        {
            if(programmed[i] != data[i])
            {
                if(error_count < 8)
                {
                    debug_printf("flash_check: %X[%x](0x%X): %x != %x\n", (uint32_t)programmed, i, (uint32_t)&programmed[i], programmed[i], data[i]);
                }
                error_count++;
            }
        }
        if(error_count) debug_printf("flash_check: %u errors\n", error_count);
        return error_count;
    }
  • Tonyo,

    I see that you are using Fapi_AutoEccGeneration mode for programming.
    I see that you are programming only 0x000981FE and 0x000981FF.
    How about 0x000981FC and 0x000981FD? Did you already program these locations using Fapi_AutoEccGeneration mode?
    If yes, then programming 0x000981FE and 0x000981FF will fail due to ECC collision.

    Please search for "When using Fapi_AutoEccGeneration mode, what is the minimum number of 16-bit words that can be programmed?" in the wiki at processors.wiki.ti.com/.../C2000_Flash_FAQ .

    Let us know if you have further questions.

    Thanks and regards,
    Vamsi
  • This routine is getting chunks of up to 256 words to program into flash. It seems that the previous 256 words programming address occasionally ends in ...FC, FD and the next 256 words start at address ...FE, FF., causing this error. I am not sure what to do about this since at this point in the program it is beyond its control. Will have to think about this.
  • Tonyo,

    Ok. Let us know if you have further questions on this.

    One more thing that may help you: Please search for "Why do you use align directive (ALIGN(x)) in the linker cmd files provided in the C2000Ware examples?" in the wiki at http://processors.wiki.ti.com/index.php/C2000_Flash_FAQ#Flash_Linker_cmd_file .

    Thanks and regards,

    Vamsi

  • yes, I already have ALIGN(4) specified for all sections in my .cmd file.

    The issue is that the binary image is built by

    "%COMPILERPATH%/bin/hex2000" -boot -sci8 -b -o %PROJECTNAME%.efw %PROJECTNAME%.out

    The .efw file is then sent to CPU2 via ethercat.

    It is broken down from sci8 format to <= 256 word chunks and sent to CPU1 for flashing via shared memory.

    Somewhere in that mess of code there needs to be an algorithm that accumulates data in 8-word chunks before sending them to be flashed instead of <=256 word chunks that may not land on an 8-word boundary.

  • Tonyo,

    Ok. Can I close this post?

    Thanks and regards,
    Vamsi