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.

TMS320F280037: DCSM programming ZxOTP_CSMPSWDx locations using Flash API

Part Number: TMS320F280037
Other Parts Discussed in Thread: UNIFLASH

Hi,

I am facing a very strange problem with programming the DCSM OTP locations for TMS320F280037 device. I am using my own code loaded and running from GSRAM and use the FlashAPI for programming. I have experience with earlier TMS320 devices, that programmed value on security locations began active after reset. For TMS320F28003x it seems that programming the ZxOTP_CSMSWDx locations(selected by ZxLINKPOINTERS) cause immediately secured device. That result in fact that after using the FlashAPI 

 oReturnCheck = Fapi_issueProgrammingCommand(0x78020,Buffer,8,0,0,Fapi_AutoEccGeneration);         //the result of this operation is Fapi_Status_Success 

I am not able to verify the programmed values by running the 

oReturnCheck = Fapi_doVerify(0x78020, 8/2, Buffer32, &oFlashStatusWord);

The returned value of oReturnCheck  is always Fapi_Error_Fail. Also the memory browser in CCS after Fapi_issueProgrammingCommand becomes all zeros. It seems that device becomes locked without any reset.

I have checked the status of DCSM after Fapi_issueProgrammingCommand by running code:

oSecureCheck = DCSM_getZone1CSMSecurityStatus();

The oSecureCheck become the value DCSM_STATUS_SECURE.

So now I try to unlock the DCSM by running the code:

            //dummy read
            DCSM_readZone1CSMPwd();

            // driverlib struct for csmKey.
            DCSM_CSMPasswordKey psCMDKey;

            psCMDKey.csmKey0 = (uint32_t)data[0] | ((uint32_t)data[1] << 16);
            psCMDKey.csmKey1 = (uint32_t)data[2] | ((uint32_t)data[3] << 16);
            psCMDKey.csmKey2 = (uint32_t)data[4] | ((uint32_t)data[5] << 16);
            psCMDKey.csmKey3 = (uint32_t)data[6] | ((uint32_t)data[7] << 16);

            // Unlock the zone 1, driverlib.
            DCSM_unlockZone1CSM(&psCMDKey);

            oSecureCheck = DCSM_getZone1CSMSecurityStatus();

but the  oSecureCheck has also the value DCSM_STATUS_SECURE and not the DCSM_STATUS_UNSECURE(i expect this value). I am sure that the csmKey have the correct values.

When I check the programmed data in DCSM using the UniFlash tool, the programmed DCSM memory have correct CSMPSWD values. 

The question is: How can I verify the programmed values on CSMPSWD locations?

Thank you for any help.

Best regards,

Tomas

  • Hi Tomas,

    When a read is performed on the CSM password locations, it will load the passwords into a hidden register that is compared against the CSMKEY. This determines whether the zone is locked or not.

    Unfortunately this will cause the DCSM to become locked before all settings are programmed in the USER OTP and cause a flash programming error. To get around this, you need to disable Verify after Programming in the CCS On-Chip flash tool. Let me know if you have any questions on how to do this.

    You can disable verify on USER OTP programming only by specifying an ignored address range that contains the USER OTP when programming your application and leaving verify checked. Then program again with just the USER otp settings with verify unchecked.

    There is also the option to program your CSMPSWDs only which will lock the zone. Then you can unlock and program the entire application including security settings. Since you have unlocked, the CSMKEYs will match the password in USER OTP, so the reading of the CSM passwords will not lock the zone.

    Let me know if you have any questions.

    Thank you,

    Luke

  • Forgot to mention, if there is an error in programming your passwords or some setting in the USER otp, the SECERRSTAT.ERR bit will be set. You can use this bit to determine whether your OTP settings were programmed correctly.

  • Hi Luke,

    thanks for your reply. Ok, I add to my code checking the SECERRSTAT.ERR bit, but i still don't understand why code below doesn't work. I attach the sample code for programming the CSMPSWD locations(0x78020 - x78027). This locations is the active ZoneSelectBlock1 for default values of Z1LinkoPointers with value 0x3FFF.

            uint16 au16DataBuffer[8] = {0x2222, 0x1111, 0xFFFF, 0x4D7F, 0x4444, 0x3333, 0x6666, 0x5555};
            uint32 u32Index = 0x78020;
    
            oSecureCheck = DCSM_getZone1CSMSecurityStatus();    //get status DCSM_STATUS_UNSECURE
            VerifyFlag = DCSM_getZone1ControlStatus();          //Get value 0x60
    
            oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,au16DataBuffer,8,0,0,Fapi_AutoEccGeneration);   //result aj Fapi_Status_Success
            while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
            if(oReturnCheck != Fapi_Status_Success){
                break;
            }
    
            dataval= DcsmCommonRegs.SECERRSTAT.all;     //Get value 0x0
            if ((dataval&0x1) == 1){
                oReturnCheck = Fapi_Error_NoActiveCommand;  //Set some error code to return
                break;
            }
    
            //DCSM_secureZone1();   //this command can be here or not
    
            // driverlib struct for csmKey.
            DCSM_CSMPasswordKey psCMDKey;
            psCMDKey.csmKey0 = (uint32_t) au16DataBuffer[0] | ((uint32_t) au16DataBuffer[1] << 16); //0x11112222
            psCMDKey.csmKey1 = (uint32_t) au16DataBuffer[2] | ((uint32_t) au16DataBuffer[3] << 16); //0x4D7FFFFF
            psCMDKey.csmKey2 = (uint32_t) au16DataBuffer[4] | ((uint32_t) au16DataBuffer[5] << 16); //0x33334444
            psCMDKey.csmKey3 = (uint32_t) au16DataBuffer[6] | ((uint32_t) au16DataBuffer[7] << 16); //0x55556666
            //dummy read
            DCSM_readZone1CSMPwd();
            // Unlock the zone 1, driverlib.
            DCSM_unlockZone1CSM(&psCMDKey);
    
            oSecureCheck = DCSM_getZone1CSMSecurityStatus();     //get status DCSM_STATUS_SECURE, I expect DCSM_STATUS_UNSECURE
            VerifyFlag = DCSM_getZone1ControlStatus();           //Get value 0x64
    
            oReturnCheck = Fapi_doVerify((uint32 *)u32Index, 8/2, Buffer32+(i/2), &oFlashStatusWord);   //get result Fapi_Status_Fail

    Why the DCSM module can't be set to unsecure state? Is there something wrong?

    Is it needed to reset the device after program the DCSM "active"  CSMPSWD locations? And only after this reset, the device can be unsecured?

    Thank you!

    Best regards,

    Tomas

  • Hi Tomas,

    Can you verify that your chosen passwords have been programmed in the memory browser at address 0x78020?

    Thank you,

    Luke

  • Hi Luke,

    I am attaching the screen shot of readed values from address 0x78020 using UniFlash tool. The unlock have been performed using the programmed password.

    So, the password is programmed succesfull in accordance with code posted in myu reply above. any idea, why the DCSM is not UNSECURED?

    Thank you,

    Tomas

  • Hi Tomas,

    Perhaps the CSMKEYs are not being programmed correctly. Could you set a breakpoint after the DCSM_unlockZone1CSM(&psCMDKey) call and check the Z1_CSMKEY register?

    Thank you,

    Luke

  • Hi Luke,

    the CSMKEYs are programmed correctly. If not, I shouldn't been able to read the content using UniFlash, because device should be blocked. But device can be unlocked using the keys above(and another keys remains device blocked).

    I add the code after CSM_unlockZone1CSM(&psCMDKey):

                // Unlock the zone 1, driverlib.
                DCSM_unlockZone1CSM(&psCMDKey);
    
                dataval= DcsmZ1Regs.Z1_CSMKEY0;     //read 0x11112222
                dataval= DcsmZ1Regs.Z1_CSMKEY1;     //read 0x4D7FFFFF
                dataval= DcsmZ1Regs.Z1_CSMKEY2;     //read 0x33334444
                dataval= DcsmZ1Regs.Z1_CSMKEY3;     //read 0x55556666    
    
                oSecureCheck = DCSM_getZone1CSMSecurityStatus();
                VerifyFlag = DCSM_getZone1ControlStatus();

    registers have the expected values, but the DCSM_getZone1CSMSecurityStatus still have the status DCSM_STATUS_SECURE.

    Any idea?

    Tomas

  • Hi Tomas,

    When setting a breakpoint after oSecureCheck = DCSM_getZone1CSMSecurityStatus();, are you able to read memory in the memory browser? This would indicate that the Zone is unlocked.

    If you add a delay before oSecureCheck = DCSM_getZone1CSMSecurityStatus();, does it still have the status of DCSM_STATUS_SECURE?

    Thank you,

    Luke

  • Hi Luke,

    "When setting a breakpoint after oSecureCheck = DCSM_getZone1CSMSecurityStatus();, are you able to read memory in the memory browser? This would indicate that the Zone is unlocked."

    No, the whole flash has value 0x0000.

    "If you add a delay before oSecureCheck = DCSM_getZone1CSMSecurityStatus();, does it still have the status of DCSM_STATUS_SECURE?"

    what delay? 1ms/1s/10s? II think that this is not important because whne I debug the code I move across the lines in steps of seconds.

    This is the point - the passwords are programmed succesfully, the uniflash can unlock the device using this passwords but code above not. I mention, that I run my code from unsecured GSRAM...may it be the reason?

    Tomas

  • Hi Tomas,

    Could you try flipping the endianness of each of the keys? Aka change the following code:

    psCMDKey.csmKey0 = (uint32_t) au16DataBuffer[0] | ((uint32_t) au16DataBuffer[1] << 16); //0x11112222
            psCMDKey.csmKey1 = (uint32_t) au16DataBuffer[2] | ((uint32_t) au16DataBuffer[3] << 16); //0x4D7FFFFF
            psCMDKey.csmKey2 = (uint32_t) au16DataBuffer[4] | ((uint32_t) au16DataBuffer[5] << 16); //0x33334444
            psCMDKey.csmKey3 = (uint32_t) au16DataBuffer[6] | ((uint32_t) au16DataBuffer[7] << 16); //0x55556666

    to

    psCMDKey.csmKey0 = (uint32_t) au16DataBuffer[1] | ((uint32_t) au16DataBuffer[0] << 16); //0x11112222
            psCMDKey.csmKey1 = (uint32_t) au16DataBuffer[3] | ((uint32_t) au16DataBuffer[2] << 16); //0x4D7FFFFF
            psCMDKey.csmKey2 = (uint32_t) au16DataBuffer[5] | ((uint32_t) au16DataBuffer[4] << 16); //0x33334444
            psCMDKey.csmKey3 = (uint32_t) au16DataBuffer[7] | ((uint32_t) au16DataBuffer[6] << 16); //0x55556666

    Thank you,

    Luke

  • Hi Luke,

    yes, I have tried it several times before your post, but change of endianess has no effect.

    Tomas

  • Hi Tomas,

    Understood, I will test your code on my side to determine the root cause. I will get back to you this week.

    Thank you,

    Luke

  • Hi Luke,

    any news?

  • Hi Tomas,

    What are your GRABRAM and GRABSECT bits programmed to? I recreated this on my side and was able to unlock the zone using the code you provided, but only after programming all of the GRABSECT / GRABRAM fields to "10". This is because if a zone is locked and a GRABSECT / GRABRAM field is programmed to default 11, the corresponding memory region will be inaccessible.

    Are you able to step over the code that configures the CSM keys and observe the changes in the register window?

    Thank you,

    Luke