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.

Concerto Flash API

Other Parts Discussed in Thread: CONTROLSUITE

Hello,

I'm having trouble writing to flash on the C28 core.  I can run the flash API example code for both cores, and it works fine.  Now I have created my own project and I'm trying to build a bootloader, but I can't get it to burn flash on the C28 side.  I have copied each step from the example and placed it in my code, but it still doesn't work.  

Every API call results in a "success" status, including the Fapi_issueAsyncCommandWithAddress commands to erase and program.  But nothing in the memory browser window changes, and the verify and blank check steps fail because flash didn't really change.

I've looked at the example code a hundred times and I'm sure I'm doing the same steps in the same order.  Any idea what I could be missing?  Something outside the code, like a project setting or something?  I'm lost.

Thanks,
Joel 

  • Joel,

    Try below hints. 

    1.  Make sure to grab the pump semaphore 

    2.  Make sure the device is unlocked.

    3.  Make sure to pass the correct system frequency (frequency at which CPU is operating) to Fapi_initializeAPI( ) function.

    4.  Make sure to set the wait states correctly depending on the system frequency.    

    If you need any help, please let us know.

    Thanks and regards,
    Vamsi

  • Thanks for the quick response. 

    I'm pretty sure I'm doing all of those things just like the example does them.  I'm getting the semaphore.  I have copied and pasted the SysCtlClockConfigSet line from the M3 example into my M3 code, and I've copied and pasted the Fapi_initializeAPI call from the C28 example code into my C28 code.  My C28 system is running at 150MHz and I'm using 3 wait states; just like the example. 

    But, when you say "make sure the device is unlocked" are you talking about calling the CSMUnlock function?  I'm doing that, but is there some other lock that I'm not aware of?

    That's the kind of thing I'm looking for since the commands seem to just get ignored.  They run successfully, but have no effect.  As if the Flash is locked or something.

    Thanks,
    Joel

     

  • Vamsi,

    I found a clue.  My C28 program is writing to flash when it receives a command from the M3.  I'm using an IPC ISR like this...

    ==============================

    interrupt void MtoC_IPC_ISR (void)
    {
          // Check for command from M3 side
          switch (CtoMIpcRegs.MTOCIPCCOM){
                  case IPC_DATA_WRITE_32:
                          IPCLiteMtoCDataWrite(IPC_FLAG1, IPC_FLAG32);
                          break;
                 case IPC_DATA_READ_32:
                          IPCLiteMtoCDataRead(IPC_FLAG1, IPC_FLAG32);
                         break;
                 case IPC_FUNC_CALL:
                         IPCLiteMtoCFunctionCall(IPC_FLAG1, IPC_FLAG32);              
                         break;
                 default:
                         break;

    }
    // IPC Lite Driver Functions acknowledge the IPC interrupt.
    // There is no need to ACK the IPC interrupt flag separately.
    //
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP11; // Acknowledge interrupt to PIE
    }

    ==============================

    I am using the IPCLiteMtoCFunctionCall to call a function on the C28 side, and that function results in a write to flash.  But that doesn't work.  I get the command and call the function to write flash, but the values don't change in the memory window.  If I just call the function from main (no IPC command, no interrupt) I'm able to see flash change.

    Should I be able to do this with an IPC function call?  Any idea why that wouldn't work?

    Thanks,
    Joel 

  • Joel,

    I don't see any issue in using IPCLiteMtoCFunctionCall to call a function on the C28 side to invoke Flash program.  Did you check whether both the task flag and status flag are being acknowledged by C28x to make sure that the function call is really happening?  Make sure the command from Master is a function call command and that the correct address for the function is given.  I will let our software team to further help you on the IPC lite functionality.

    On the questions that you have about the Flash erase and program calls returning success status, Fapi_issueAsyncCommandWithAddress() function always returns success as given in the API documentation to indicate the erase command is given to Flash state machine.  It does not verify whether the FSM completed erase or not.  Users have to check the status of the FSM using Fapi_checkFsmForReady() to know whether the FSM is still busy with prior command or is it done.  Users have to check the FMSTAT register using Fapi_getFsmStatus() to know if FSM operation has resulted in any of the failures/status described in FMSTAT register in API documentation.  Similarly Fapi_issueProgrammingCommand() returns a success status unless the errors mentioned in the API documentation occur for this function.  Verify and blank check functions have to be used to know the flash contents. 

    Also you need to remember that Flash API does not enable writes to protected registers.  Users have to include "EALLOW" statement before calling API functions to make sure that the API writes to flash registers go through.  Could you check if you are missing EALLOW before calling API functions when you use IPC lite functions?

    On your concern regarding security, as you mentioned you need to use unlock functions to unlock the device.  If you program any value other than all 0xFFFF in password locations, you need to make sure you write that password in KEY registers to unlock the device.

    Thanks and regards,
    Vamsi

  • Vamsi,

    I put a breakpoint on the C28 function called by the IPC function call, and I saw it get there.    This is that function...

    ============================================

    uint32 ReceiveCommand(ulong ulCommand)
    {
    uint32 ulStatus;

    switch (ulCommand) {
    case 0: ulStatus = HandleJumpCmd(); break;
    case 1: ulStatus = HandleEraseCmd(); break;
    case 2: ulStatus = HandleProgramChunkCmd(); break;
    case 3: ulStatus = HandleValidateCmd(); break;
    default: break;
    }
    return ulStatus;
    }

    ===================================================

    The function above then calls HandleProgramChunkCmd, which is shown below...

    ===================================================

    uint32 HandleProgramChunkCmd(void)
    {
            // Other stuff in here....

    ulStatus = Flash_CopyChunkToFLASH();

    }

    ==========================================

    And then Flash_CopyChunkToFlash calls the flash API.  I can see it get to that API call but flash doesn't change.  If I move Flash_CopyChunkToFlash into main() it works every time.  

    Thanks,
    Joel 

  • Joel,

    Did you check my question below posted in earlier reply on this thread?

    Also you need to remember that Flash API does not enable writes to protected registers.  Users have to include "EALLOW" statement before calling API functions to make sure that the API writes to flash registers go through.  Could you check if you are missing EALLOW before calling API functions when you use IPC lite functions?

    You might have EALLOW in main() before calling the API functions and hence it might be working.

    Please check whether EALLOW is set or not when you use HandleProgramChunkCmd() from IPC Lite functions.

    Thanks and regards,

    Vamsi

  • Vamsi,

    You're right.  That was the problem.  I really thought I had EALLOW before those API calls, but I guess they were in functions that were happening before the IPC functions, and maybe there was an EDIS somewhere in one of the IPC functions.

    Thanks a lot for the help,

    Joel 

  • Hello,

    I just run into the same trap! I just found it out by myself but it cost me too much time since I was not sure wheter I was doing something wrong with my RAM linker cmd file...

    Please include a comment or hint in your flash API example! My application will gain/release the flash pump before/after accessing (write/erase) the flash. In these library functions (FlashGainPump() / FlashLeavePump()) an EALLOW and EDIS are (correctly) included.

    In my opinion the Flash API should actually take care of this protection by itself!

    Also I would prefer a non blocking version for FlashGainPump() function, now I'm checking the status of the semaphore before calling this function myself.

    Regards,
    Stefan



  • Hi Stefan,

    F021 Flash API reference guide mentions in the Flash API overview chapter that writes to protected registers should be enabled by users.  But I will take your suggestion to mention the same in the Flash API example comments.  I understand that implementing the protected register write enable in API makes it easy for users; but in order to easily maintain the Flash API software across different platforms/cores we did not implement it in API.

    We agree with you on providing a non-blocking version of FlashGainPump() function.  We will update the function in next revision of controlsuite.

    Thanks and regards,
    Vamsi 

  • Hello Vamsi,

    all right, I found the hint in chapter 2.1 of Flash API documentation, missed it before.
    Maybe a hint should be placed as well in the chapter 3 within the detailed description of the concerned functions...

    It is tricky since the return code will not give you a hint of that issue. That's why it was difficult for me to track the problem.
    But I do understand that you can't check the register protection state...

    So it is always mandatory to do a verify after a erase/write function call, unlike the following comment in the example code:
    // Verify the values programmed.  The Program step itself does a verify
    // as it goes.  This verify is a 2nd verification that can be done.

    A way to be flexible across different platforms you could include a mandatory hookup-function which provides the dedicated code for (un)locking the protected registers similar to the watchdog-timer call functions?

    Best regards,
    Stefan

  • Vamsi,

    I forgot to mention another thread which I run into yesterday, maybe it should be mentioned in the flash API documentation as well.

    http://e2e.ti.com/support/microcontrollers/c2000/f/171/t/30583.aspx

    As far as I understand, all functions being called during a flash erase / program should reside in RAM?

    As for my part I worte two macros enclosing all of the FlashAPi function calls for C28:

    #define FLASHAPI_FUNCTION_CALL_START()  {DINT; EALLOW;}
    #define FLASHAPI_FUNCTION_CALL_END()    {EDIS; EINT;}

    and for ARM M3:

    #define FLASHAPI_FUNCTION_CALL_START()  {HWREG(SYSCTL_MWRALLOW) = 0xA5A5A5A5;IntMasterDisable();}
    #define FLASHAPI_FUNCTION_CALL_END()    {HWREG(SYSCTL_MWRALLOW) = 0x00000000;IntMasterEnable();}

    Just as a suggestion adding these to your example code.

    Stefan