TMS320F28P650DK: TMS320F28P65x: Unable to program more than 16 bytes into Flash Bank1 using Flash API v3.00.02.00 and Fapi_doVerify() fails when programming

Part Number: TMS320F28P650DK
Other Parts Discussed in Thread: C2000WARE

Hello TI Team,

I am currently working on programming data into a specific flash bank (Bank 1) on an F28P65x device using the Flash API v3.00.02.00.
I am able to successfully erase and program the flash sector at the following address:

FLASH_BANK1_START_ADDR      0x0A0000U" Flash Bank 1
 However, I’ve observed a repeatable issue when programming more than 17 bytes of data. 
#define FLASH_BANK0_START_ADDR      0x080000U
#define FLASH_BANK1_START_ADDR      0x0A0000U
#define FLASH_BANK2_START_ADDR      0x0C0000U
#define FLASH_BANK3_START_ADDR      0x0E0000U
#define FLASH_BANK4_START_ADDR      0x100000U

#define VIN_FLASH_ADDR              FLASH_BANK1_START_ADDR
#define VIN_SECTOR_SIZE             0x0800U     // 2 KB sector
#define VIN_LEN_BYTES               17U         // VIN length
#define VIN_PAYLOAD_BYTES           24U         // padded to 8-byte multiple
#define VIN_PAYLOAD_WORDS           12U         // 24 / 2
#define VIN_MAX_HALFWORDS           (VIN_PAYLOAD_BYTES / 2U)
#define FSM_STATUS_SUCCESS          (0x3U)
status = Fapi_doVerify(dest, 4U, (uint32_t *)&vin_buf[i], &flashStatusWord);,but when i comment this Fapi_doverify,i m able to write into the sector but upto 16-Bytes data (8-Word).
 
Note: 1.Why does the following verify call fail every time when I try to program more than 16 bytes (for example, 17 or 24 bytes)?  
2.What is the maximum number of bytes (or halfwords) that can be programmed into a flash sector in a single call to Fapi_issueProgrammingCommand() on the F28P65x device? 
3.Is it possible to perform firmware update (in-application programming) using Flash API v3.00.02.00 on F28P65x? via CAN.
 
Fapi_StatusType VIN_ProgramUsingAutoECC(const uint8_t *vin_bytes)
{
    Fapi_StatusType status = Fapi_Status_Success;
    Fapi_FlashStatusWordType flashStatusWord;
    Fapi_FlashStatusType fsmStatus;
    
    uint16_t vin_buf[VIN_PAYLOAD_WORDS + 8] __attribute__((aligned(8)));
    uint16_t i;
    uint32_t prog_halfwords;

    memset(vin_buf, 0xFF, sizeof(vin_buf)); 

    for (i = 0; i < VIN_LEN_BYTES; i += 2U) {
        uint16_t lo = vin_bytes[i];
        uint16_t hi = (i + 1U < VIN_LEN_BYTES) ? vin_bytes[i + 1U] : 0xFFU;
        vin_buf[i / 2U] = (uint16_t)((hi << 8) | lo);
    }
    /* 2) pad to 4-halfword (8-byte) boundary */
    prog_halfwords = VIN_WORDS_16BIT;
    
    IPC_claimFlashSemaphore(IPC_FLASHSEM_OWNER_CPU1);

    status = Fapi_setActiveFlashBank(Fapi_FlashBank1);
    if (status != Fapi_Status_Success) {
        printf("[VIN] Bank select failed: %d\n", status);
        IPC_releaseFlashSemaphore();
        return status;
    }

    Flash_disablePrefetch(FLASH0CTRL_BASE);
    Flash_disableCache(FLASH0CTRL_BASE);
    ClearFSMStatus();

    Fapi_setupBankSectorEnable(FLASH_WRAPPER_PROGRAM_BASE + FLASH_O_CMDWEPROTA, 0x00000000U);
    Fapi_setupBankSectorEnable(FLASH_WRAPPER_PROGRAM_BASE + FLASH_O_CMDWEPROTB, 0x00000000U);
    DEVICE_DELAY_US(50);

    for (i = 0; i < prog_halfwords; i += 4U) {
        uint32_t *dest = (uint32_t *)(VIN_FLASH_ADDR + (i * 2U)); 

        ClearFSMStatus();

        status = Fapi_issueProgrammingCommand(
            dest,
            &vin_buf[i],
            8U,
            NULL,
            0,
            Fapi_AutoEccGeneration
        );
        if (status != Fapi_Status_Success) {
            Flash_enablePrefetch(FLASH0CTRL_BASE);
            Flash_enableCache(FLASH0CTRL_BASE);
            IPC_releaseFlashSemaphore();
            return status;
        }

        while (Fapi_checkFsmForReady() == Fapi_Status_FsmBusy) { }

        DEVICE_DELAY_US(20);

        fsmStatus = Fapi_getFsmStatus();
        if (status != Fapi_Status_Success)
         {
            printf("[VIN] Programming failed @0x%06lX (status=%d, FSM=0x%08lX)\n",
                   (unsigned long)dest, (int)status, (unsigned long)fsmStatus);
            Flash_enablePrefetch(FLASH0CTRL_BASE);
            Flash_enableCache(FLASH0CTRL_BASE);
            IPC_releaseFlashSemaphore();
            return Fapi_Error_Fail;
        }

        status = Fapi_doVerify(dest, 4U, (uint32_t *)&vin_buf[i], &flashStatusWord);
         
        if (status != Fapi_Status_Success) {
            Flash_enablePrefetch(FLASH0CTRL_BASE);
            Flash_enableCache(FLASH0CTRL_BASE);
            IPC_releaseFlashSemaphore();
            return status;
        }
    }
    /* 10) Re-enable prefetch/cache (and ECC if you disabled it) */
    Flash_enablePrefetch(FLASH0CTRL_BASE);
    Flash_enableCache(FLASH0CTRL_BASE);
    IPC_releaseFlashSemaphore();
    return Fapi_Status_Success;
}
  • Hi Suresh,

    If start address is 128-bit aligned, then either 8 or 4 16-bit words should be programmed at the same time as needed. If the start address is 64-bit aligned but not 128-bit aligned, then only 4 16-bit words should be programmed at the same time. You have to increment your loop accordingly. Alos please note that fapi_doVerify function verify 32-bit at a time, you have to adjust the length.

    Refer our Flash api example in C2000ware for more details.

    Regards,

    Rajeshwary