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.

FLASH API problem

I created a project using the FLASH API according to SPNU493A.pdf for the TMS570 MDK.

When I compile I get the error "file ../pf035a_api_eabi.lib<blank.obj> was built without VFP coprocessor support while a previously seen file was; combining incompatible files".

The output file is not generated.

Since I have no idea how to build without VFP coprocessor support, I tried to replace pf035a_api_eabi.lib with pf035a_api_eabi_vfp.lib. This eliminates the error and I am able to load the program and run it on the development board. I am able to call some of the FLASH API functions. Flash_Compact_B() and  Flash_Blank_B() return without error but Flash_Erase_Bank_B() and Flash_Prog_B() always return with an error. I am running out of bank 0 and preforming the operations on the other 3 banks (which are all blank). I disabled ECC by calling _coreDisableFlashEcc_() in _c_int00() right after the call to systemInit(). I also have interrupts disabled.

How should I resolve this? Should I build the project without VFP coprocessor support (I don't need it for this application) and include the file pf035a_api_eabi.lib per SPNU493A.pdf? If so, how do I disable VFP coprocessor support?

If pf035a_api_eabi_vfp.lib should work, what could be the problem? It would be nice to step through the code in the library routines to see why erase and programming is failing but difficult to do without the source code.

-Walt


 

 

 

  • Walt,

    Can you provide more information about the error codes that are returned for the program and erase operations?

    Regards,

    Sunil

  • Hi Sunil,

    Thanks for your reply.

    Flash_Erase_Bank_B() only returns 0 for fail and 1 for pass (it returns 0). It also writes the following values in a status structure passed to it.

    stat1 = 0 (Maximum number of compaction pulses for any one stick

    stat2 = 16 (Status register value)

    stat3 = 1 (Number of pulses applied to erase all locations)

    stat4 = 9 (Total number of compaction pulses)

    Flash_Prog_Data_B() also only returns 0 for fail or 1 for pass (it returns 0). Status registers are as followed/

    stat1 = 0x80000 (If programming failed, address of first failing location)

    stat2 = 0xFFFFFFFF (If programming failed, data at first failing location)

    stat3 = 0xFFFFF938 (If programming failed, the last MSTAT value)

    stat4 = 1 (Maximum number of pulses required to program single location)

    In this case I was running out of bank0, successfully compacted bank 1, failed erase of bank1, successfully verified bank1 was blank and failed programming 8 bytes (2 32-bit words) starting at location 0x80000.

    -Walt

     

     

  • Hello Walt,

    Quick Answer on the VFP issue:  The CCS linker will not link code compiled with Floating point support to code compiled without floating point support even if it does not use floating point operations.  Therefore we release the API compiled both ways.  If you do not want or need floating point support, remove the option from the highlighted box in the picture below

     

    On the flash programming issue, if you could post your code, I would be able to better analyze what might be going on here.

  • Hi John,

    Thanks for the VFP tip, I can now compile and run with pf035a_api_eabi.lib but still get failures with erase and program functions.

    Here is the test function. I store all arguments in variables before calling the API functions so I can verify the contents using the debugger. I also included the definitions and tables the code uses.

    -Walt

    void gvTestFlash(ubyte *pubData)
    {
        ubyte   ubIdx;
        ubyte   ubTxData[8];
        boolean fSuccess = TRUE;
        ulong   *pulStart;
        ulong   ulLength;
        ulong   ulDelay;
        FLASH_CORE      eBankNum;
        FLASH_SECT      eSectorNum;
        FLASH_ARRAY_ST  eBaseAddr;
        FLASH_STATUS_ST eFlashStatus;

        // Initialize
        ulDelay = CONST_FREQ;
        memset(&ubTxData, 0, 8);

        // Compact bank 1 (sectors 10-14)
        for( ubIdx=10; ubIdx < 14; ubIdx++ )
        {
            pulStart   = eSector[ubIdx].pvStart;
            eBankNum   = eSector[ubIdx].eBank;
            eSectorNum = (FLASH_SECT)eSector[ubIdx].ulSectorNumber;
            eBaseAddr  = (FLASH_ARRAY_ST)eSector[ubIdx].ulFlashBaseAddress;

            if ( !Flash_Compact_B(pulStart, eBankNum, eSectorNum, ulDelay, eBaseAddr, &eFlashStatus) )
            {
                fSuccess = FALSE;
                break;
            }
        }
        // Send CAN message indicating success/failure
        ubTxData[0] = ( fSuccess ) ? 1: 0;
        gfCAN_Transmit(canREG1, canMESSAGE_BOX6, (ubyte *)&ubTxData[0]);

        // Erase bank 1
        pulStart    = eBank[FLASH_CORE1].pvStart;
        ulLength    = eBank[FLASH_CORE1].ulLength;
        eBankNum    = (FLASH_CORE)eBank[FLASH_CORE1].ulBankNumber;
        eBaseAddr   = (FLASH_ARRAY_ST)eBank[FLASH_CORE1].ulFlashBaseAddress;
        fSuccess    = Flash_Erase_Bank_B(pulStart, ulLength, eBankNum, ulDelay, eBaseAddr, &eFlashStatus);

        // Send CAN message indicating success/failure
        ubTxData[0] = ( fSuccess ) ? 1: 0;
        gfCAN_Transmit(canREG1, canMESSAGE_BOX7, (ubyte *)&ubTxData[0]);

        // Verify core 1 is erased
        pulStart    = eBank[FLASH_CORE1].pvStart;
        ulLength    = eBank[FLASH_CORE1].ulLength;
        eBankNum    = (FLASH_CORE)eBank[FLASH_CORE1].ulBankNumber;
        eBaseAddr   = (FLASH_ARRAY_ST)eBank[FLASH_CORE1].ulFlashBaseAddress;
        fSuccess    = Flash_Blank_B(pulStart, ulLength, eBankNum, eBaseAddr, &eFlashStatus);

        // Send message indicating success/failure
        ubTxData[0] = ( fSuccess ) ? 1: 0;
        gfCAN_Transmit(canREG1, canMESSAGE_BOX8, (ubyte *)&ubTxData[0]);

        // Program 8 bytes received in CAN message
        pulStart   = eSector[10].pvStart;
        eBankNum   = eSector[10].eBank;
        eBaseAddr  = (FLASH_ARRAY_ST)eSector[10].ulFlashBaseAddress;
        fSuccess   = Flash_Prog_B(pulStart, (ulong *)pubData, 2, eBankNum, ulDelay, eBaseAddr, &eFlashStatus);

        // Send CAN message indicating success/failure
        ubTxData[0] = ( fSuccess ) ? 1: 0;
        gfCAN_Transmit(canREG1, canMESSAGE_BOX9, (ubyte *)&ubTxData[0]);
    }

        #define CONST_FREQ 8    // Value is half of HCLK, run from Oscillator, HCLK should be 16MHz

        typedef struct Sectors
        {
            void *pvStart;            // Start address of sector
            ulong ulLength;           // Sector length (number of 32-bit words)
            FLASH_CORE eBank;         // Bank number  
            ulong ulSectorNumber;     // Sector number
            ulong ulFlashBaseAddress; // Base address
        }SECTORS;

        typedef struct Banks
        {
            void * pvStart;
            ulong ulLength;           // number of 32-bit words
            ulong ulBankNumber;
            ulong ulFlashBaseAddress;
            ulong ulPsa; 
        }BANKS;

        #define NUMBEROFSECTORS 22
        const SECTORS eSector[NUMBEROFSECTORS]=
        {
            (void *)0x00000000, 0x08000>>2, FLASH_CORE0, 0, 0xfff87000, //  0
            (void *)0x00008000, 0x08000>>2, FLASH_CORE0, 1, 0xfff87000, //  1
            (void *)0x00010000, 0x08000>>2, FLASH_CORE0, 2, 0xfff87000, //  2
            (void *)0x00018000, 0x02000>>2, FLASH_CORE0, 3, 0xfff87000, //  3
            (void *)0x0001A000, 0x02000>>2, FLASH_CORE0, 4, 0xfff87000, //  4
            (void *)0x0001C000, 0x04000>>2, FLASH_CORE0, 5, 0xfff87000, //  5
            (void *)0x00020000, 0x10000>>2, FLASH_CORE0, 6, 0xfff87000, //  6
            (void *)0x00030000, 0x10000>>2, FLASH_CORE0, 7, 0xfff87000, //  7
            (void *)0x00040000, 0x20000>>2, FLASH_CORE0, 8, 0xfff87000, //  8
            (void *)0x00060000, 0x20000>>2, FLASH_CORE0, 9, 0xfff87000, //  9
            (void *)0x00080000, 0x20000>>2, FLASH_CORE1, 0, 0xfff87000, // 10
            (void *)0x000A0000, 0x20000>>2, FLASH_CORE1, 1, 0xfff87000, // 11
            (void *)0x000C0000, 0x20000>>2, FLASH_CORE1, 2, 0xfff87000, // 12
            (void *)0x000E0000, 0x20000>>2, FLASH_CORE1, 3, 0xfff87000, // 13
            (void *)0x00100000, 0x20000>>2, FLASH_CORE2, 0, 0xfff87000, // 14
            (void *)0x00120000, 0x20000>>2, FLASH_CORE2, 1, 0xfff87000, // 15
            (void *)0x00140000, 0x20000>>2, FLASH_CORE2, 2, 0xfff87000, // 16
            (void *)0x00160000, 0x20000>>2, FLASH_CORE2, 3, 0xfff87000, // 17
            (void *)0x00180000, 0x20000>>2, FLASH_CORE3, 0, 0xfff87000, // 18
            (void *)0x001A0000, 0x20000>>2, FLASH_CORE3, 1, 0xfff87000, // 19
            (void *)0x001C0000, 0x20000>>2, FLASH_CORE3, 2, 0xfff87000, // 20
            (void *)0x001E0000, 0x20000>>2, FLASH_CORE3, 3, 0xfff87000  // 21
        };

        #define NUMBEROFBANKS 4
        const BANKS eBank[NUMBEROFBANKS]=
        {
            (void *) 0x00000000, 0x80000>>2, 0, 0xfff87000, 0x00000000,
            (void *) 0x00080000, 0x80000>>2, 1, 0xfff87000, 0x00000000,
            (void *) 0x00100000, 0x80000>>2, 2, 0xfff87000, 0x00000000,
            (void *) 0x00180000, 0x80000>>2, 3, 0xfff87000, 0x00000000
        };
       
        #define NUMBEROFECC_PARITYBANKS 4
        const BANKS eEcc_parity[NUMBEROFECC_PARITYBANKS]=
        {
            (void *) 0x00400000, 0x40000>>2, 0, 0xfff87000, 0x00000000,
            (void *) 0x00440000, 0x40000>>2, 1, 0xfff87000, 0x00000000,
            (void *) 0x00480000, 0x40000>>2, 2, 0xfff87000, 0x00000000,
            (void *) 0x004C0000, 0x40000>>2, 3, 0xfff87000, 0x00000000
        };

     

  • Sorry for the nasty looking code. It looked fine before I clicked post. Any idea on how to prevent this and I'll repost it.

    -Walt

     

  • Try2.

    void gvTestFlash(ubyte *pubData)
    {
        ubyte   ubIdx;
        ubyte   ubTxData[8];
        boolean fSuccess = TRUE;
        ulong   *pulStart;
        ulong   ulLength;
        ulong   ulDelay;
        FLASH_CORE      eBankNum;
        FLASH_SECT      eSectorNum;
        FLASH_ARRAY_ST  eBaseAddr;
        FLASH_STATUS_ST eFlashStatus;

        // Initialize
        ulDelay = CONST_FREQ;
        memset(&ubTxData, 0, 8);

        // Compact bank 1 (sectors 10-14)
        for( ubIdx=10; ubIdx < 14; ubIdx++ )
        {
            pulStart   = eSector[ubIdx].pvStart;
            eBankNum   = eSector[ubIdx].eBank;
            eSectorNum = (FLASH_SECT)eSector[ubIdx].ulSectorNumber;
            eBaseAddr  = (FLASH_ARRAY_ST)eSector[ubIdx].ulFlashBaseAddress;

            if ( !Flash_Compact_B(pulStart, eBankNum, eSectorNum, ulDelay, eBaseAddr, &eFlashStatus) )
            {
                fSuccess = FALSE;
                break;
            }
        }
        // Send CAN message indicating success/failure
        ubTxData[0] = ( fSuccess ) ? 1: 0;
        gfCAN_Transmit(canREG1, canMESSAGE_BOX6, (ubyte *)&ubTxData[0]);

        // Erase bank 1
        pulStart    = eBank[FLASH_CORE1].pvStart;
        ulLength    = eBank[FLASH_CORE1].ulLength;
        eBankNum    = (FLASH_CORE)eBank[FLASH_CORE1].ulBankNumber;
        eBaseAddr   = (FLASH_ARRAY_ST)eBank[FLASH_CORE1].ulFlashBaseAddress;
        fSuccess    = Flash_Erase_Bank_B(pulStart, ulLength, eBankNum, ulDelay, eBaseAddr, &eFlashStatus);

        // Send CAN message indicating success/failure
        ubTxData[0] = ( fSuccess ) ? 1: 0;
        gfCAN_Transmit(canREG1, canMESSAGE_BOX7, (ubyte *)&ubTxData[0]);

        // Verify core 1 is erased
        pulStart    = eBank[FLASH_CORE1].pvStart;
        ulLength    = eBank[FLASH_CORE1].ulLength;
        eBankNum    = (FLASH_CORE)eBank[FLASH_CORE1].ulBankNumber;
        eBaseAddr   = (FLASH_ARRAY_ST)eBank[FLASH_CORE1].ulFlashBaseAddress;
        fSuccess    = Flash_Blank_B(pulStart, ulLength, eBankNum, eBaseAddr, &eFlashStatus);

        // Send message indicating success/failure
        ubTxData[0] = ( fSuccess ) ? 1: 0;
        gfCAN_Transmit(canREG1, canMESSAGE_BOX8, (ubyte *)&ubTxData[0]);

        // Program 8 bytes received in CAN message
        pulStart   = eSector[10].pvStart;
        eBankNum   = eSector[10].eBank;
        eBaseAddr  = (FLASH_ARRAY_ST)eSector[10].ulFlashBaseAddress;
        fSuccess   = Flash_Prog_B(pulStart, (ulong *)pubData, 2, eBankNum, ulDelay, eBaseAddr, &eFlashStatus);

        // Send CAN message indicating success/failure
        ubTxData[0] = ( fSuccess ) ? 1: 0;
        gfCAN_Transmit(canREG1, canMESSAGE_BOX9, (ubyte *)&ubTxData[0]);
    }

    #define CONST_FREQ 8    // Value is half of HCLK, run from Oscillator, HCLK should be 16MHz

    typedef struct Sectors
    {
        void *pvStart;            // Start address of sector
        ulong ulLength;           // Sector length (number of 32-bit words)
        FLASH_CORE eBank;         // Bank number  
        ulong ulSectorNumber;     // Sector number
        ulong ulFlashBaseAddress; // Base address
    }SECTORS;

    typedef struct Banks
    {
        void * pvStart;
        ulong ulLength;           // number of 32-bit words
        ulong ulBankNumber;
        ulong ulFlashBaseAddress;
        ulong ulPsa; 
    }BANKS;

    #define NUMBEROFSECTORS 22
    const SECTORS eSector[NUMBEROFSECTORS]=
    {
        (void *)0x00000000, 0x08000>>2, FLASH_CORE0, 0, 0xfff87000, //  0
        (void *)0x00008000, 0x08000>>2, FLASH_CORE0, 1, 0xfff87000, //  1
        (void *)0x00010000, 0x08000>>2, FLASH_CORE0, 2, 0xfff87000, //  2
        (void *)0x00018000, 0x02000>>2, FLASH_CORE0, 3, 0xfff87000, //  3
        (void *)0x0001A000, 0x02000>>2, FLASH_CORE0, 4, 0xfff87000, //  4
        (void *)0x0001C000, 0x04000>>2, FLASH_CORE0, 5, 0xfff87000, //  5
        (void *)0x00020000, 0x10000>>2, FLASH_CORE0, 6, 0xfff87000, //  6
        (void *)0x00030000, 0x10000>>2, FLASH_CORE0, 7, 0xfff87000, //  7
        (void *)0x00040000, 0x20000>>2, FLASH_CORE0, 8, 0xfff87000, //  8
        (void *)0x00060000, 0x20000>>2, FLASH_CORE0, 9, 0xfff87000, //  9
        (void *)0x00080000, 0x20000>>2, FLASH_CORE1, 0, 0xfff87000, // 10
        (void *)0x000A0000, 0x20000>>2, FLASH_CORE1, 1, 0xfff87000, // 11
        (void *)0x000C0000, 0x20000>>2, FLASH_CORE1, 2, 0xfff87000, // 12
        (void *)0x000E0000, 0x20000>>2, FLASH_CORE1, 3, 0xfff87000, // 13
        (void *)0x00100000, 0x20000>>2, FLASH_CORE2, 0, 0xfff87000, // 14
        (void *)0x00120000, 0x20000>>2, FLASH_CORE2, 1, 0xfff87000, // 15
        (void *)0x00140000, 0x20000>>2, FLASH_CORE2, 2, 0xfff87000, // 16
        (void *)0x00160000, 0x20000>>2, FLASH_CORE2, 3, 0xfff87000, // 17
        (void *)0x00180000, 0x20000>>2, FLASH_CORE3, 0, 0xfff87000, // 18
        (void *)0x001A0000, 0x20000>>2, FLASH_CORE3, 1, 0xfff87000, // 19
        (void *)0x001C0000, 0x20000>>2, FLASH_CORE3, 2, 0xfff87000, // 20
        (void *)0x001E0000, 0x20000>>2, FLASH_CORE3, 3, 0xfff87000  // 21
    };

    #define NUMBEROFBANKS 4
    const BANKS eBank[NUMBEROFBANKS]=
    {
        (void *) 0x00000000, 0x80000>>2, 0, 0xfff87000, 0x00000000,
        (void *) 0x00080000, 0x80000>>2, 1, 0xfff87000, 0x00000000,
        (void *) 0x00100000, 0x80000>>2, 2, 0xfff87000, 0x00000000,
        (void *) 0x00180000, 0x80000>>2, 3, 0xfff87000, 0x00000000
    };

    #define NUMBEROFECC_PARITYBANKS 4
    const BANKS eEcc_parity[NUMBEROFECC_PARITYBANKS]=
    {
        (void *) 0x00400000, 0x40000>>2, 0, 0xfff87000, 0x00000000,
        (void *) 0x00440000, 0x40000>>2, 1, 0xfff87000, 0x00000000,
        (void *) 0x00480000, 0x40000>>2, 2, 0xfff87000, 0x00000000,
        (void *) 0x004C0000, 0x40000>>2, 3, 0xfff87000, 0x00000000
    };

  • Are you setting the PLL or running the device at OscIn frequency?

    One other thing, the commands Flash_Blank_B(), Flash_Verify_Data_B(), Flash_Verify_Zeros_B(), Flash_Verify_PSA_B() need to execute from RAM.

  • I am using the PLL.

    One other thing, the commands Flash_Blank_B(), Flash_Verify_Data_B(), Flash_Verify_Zeros_B(), Flash_Verify_PSA_B() need to execute from RAM.

    SPNA117 - Programming TMS570 Flash Using Flash API suggests you can...

    "F035 Flash offers the possibility of erasing/programming one bank while executing code in another bank. No attempts should be made to read from Flash locations in the same bank as the area being operated on by the Flash State Machine until the command completes. For example, appropriate code in bank0 sector 0 can erase bank2 but can NOT erase bank0 sector 3."

    Like I mentioned I'm executing out of bank0 and trying to erase/program bank1 so if you are right, that is probably the problem. Am I misunderstanding SPNA117 or is it in error?

    -Walt

     

  • What speed are you setting the PLL to run at?

     

    The statement in SPNA117 is valid for most functions except a few of them that do margin reads of the Flash for verification purposes.  This is due to the fact that the margin modes effect the entire Flash instead of a single bank.  That is why I mentioned the functions I did in the previous post.

  • The PLL is set at 100Mhz.

    -Walt

  • After a further discussions with Walt off forum, we have determined the issue was with the delay parameter he was passing to the Flash API routines.  He was setting the PLL to have a 100MHz clock which should have a 50 for the wait value, but he was passing a value of 8.  Once he corrected this value, he was able to erase and program the device.