Other Parts Discussed in Thread: C2000WARE
Tool/software:
Hi,
Im working on a project which is structured such that I have a secondary bootloader on the first few sectors of bank0 from 0x80000 and the bootable application on the remaining sectors from 0x87000. The basic idea is on receiving a boot request I perform a forced watchdog reset which would then get the control to bootloader at 0x80000 which would then receive the rest of the boot commands and perform bank erase and then upgrade the application and then verify the application on the flash using the linker crc check.
The issue Im facing now is that for some reason the flash erase function does not erase and the control gets stuck for approx 1.4sec before I see that the flash erase failed (Im detect this with some gpio toggles where I have a gpio toggling every 250usec and another gpio set if the Fapi_doBlankCheck returns non success)
Here is the flashprogramming.c file;
#include "flash_programming.h" #include "F021_F28003x_C28x.h" #include "gpio_config.h" /******************************************************************************/ /*-----------------------------------Macros-----------------------------------*/ /******************************************************************************/ /** * \def * \brief */ #define SECTOR_8KB_32_LENGTH 0x800U /** * \def * \brief */ #define FLASH_BANK0_START_ADDRESS 0x80000U /** * \def * \brief */ #define FLASH_BANK0_SECTOR_START_ADDRESS 0x80000U /** * \def * \brief */ #define FLASH_BANK0_APP_SECTOR_START_ADDRESS 0x87000U /** * \def * \brief */ #define FLASH_BANK1_START_ADDRESS 0x90000U #define FLASH_BANK1_END_ADDRESS 0x9F000U /** * \def * \brief */ #define FLASH_BANK0_BOOTLOADER_MASK 0x007FU #define FLASH_ERA_PUL_MAX_ERA_PUL_M 0xFFFU // Flash Max Erase Pulses Mask #define OPT_ENABLE 0x5U // Flash Optimization Enable #define OPT_DISABLE 0x2U // Flash Optimization Disable #define MAX_ERASE_PULSE 0x7D0U // Flash Max Erase Pulses #define FLASH_O_ACC_EP 0x148U // Flash Accumulated Erase Pulses #define FLASH_O_ERA_PUL 0x136U // Flash Max Erase Pulses #define FLASH_O_OPT 0x144U // Flash Optimization /******************************************************************************/ /*--------------------------------Enumerations--------------------------------*/ /******************************************************************************/ /** * \enum * \brief */ typedef enum { FLASH_SECTOR_ERASE_CHECK = 0, //!< Flash upgrade is in initialization state FLASH_UPGRADE_ERASE = 1, //!< Flash upgrade is in erase state FLASH_UPGRADE_PROGRAM = 2, //!< Flash upgrade is in programming state FLASH_UPGRADE_END //!< Flash upgrade end state }Flash_Upgrade_State; /******************************************************************************/ /*-----------------------------Data Structures--------------------------------*/ /******************************************************************************/ /** * \struct * \brief */ /** * \union * \brief */ /******************************************************************************/ /*------------------------------Global variables------------------------------*/ /******************************************************************************/ /** \var Description = \n Type = \n Initial value = \n Range = */ #pragma DATA_SECTION(program_buffer,"DataBufferSection"); uint16_t program_buffer[MAX_SINGLE_FLASH_WRITE + 1]; uint32_t *program_buffer_ptr = (uint32_t *)program_buffer; /******************************************************************************/ /*-------------------------Function Prototypes--------------------------------*/ /******************************************************************************/ /** *\brief *\param[in] *\param[out] *\return *\author *\date */ Fapi_StatusType flash_erase_bank(uint32 *selected_bank_address, uint16_t sector_mask); /** *\brief *\param[in] *\param[out] *\return *\author *\date */ Fapi_StatusType flash_program(uint16_t *buffer, uint32_t bank_selected_address, uint16_t data_length); /******************************************************************************/ /*-------------------------Function Implementations---------------------------*/ /******************************************************************************/ /******************************************************************************/ /*-----------------------------Function Header--------------------------------*/ /******************************************************************************/ /* Function name : Function ID : Purpose of the function : Global Variables Referred : Global Variables Modified : Functions called : Arguments : Return Values : */ #ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(flash_upgrade, ".TI.ramfunc"); #endif uint16_t flash_upgrade(uint16_t *buffer, uint32_t base_address, uint16_t data_length) { Fapi_StatusType return_status; uint16_t ret_val; //program the flash with data return_status = flash_program(buffer, base_address, data_length); if (Fapi_Status_Success == return_status) { // GPIO_LED_G_SET(); ret_val = 0u; } else { // GPIO_LED_G_CLEAR(); ret_val = 1u; } return ret_val; } /******************************************************************************/ /*-----------------------------Function Header--------------------------------*/ /******************************************************************************/ /* Function name : Function ID : Purpose of the function : Global Variables Referred : Global Variables Modified : Functions called : Arguments : Return Values : */ #ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(flash_init, ".TI.ramfunc"); #endif void flash_init(void) { Fapi_StatusType return_check; program_buffer_ptr = (uint32_t *)program_buffer; return_check = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, DEVICE_SYSCLK_FREQ); if(return_check != Fapi_Status_Success) { // Check Flash API documentation for possible errors } return_check = Fapi_setActiveFlashBank(Fapi_FlashBank0); if(return_check != Fapi_Status_Success) { // Check Flash API documentation for possible errors } } /******************************************************************************/ /*-----------------------------Function Header--------------------------------*/ /******************************************************************************/ /* Function name : Function ID : Purpose of the function : Global Variables Referred : Global Variables Modified : Functions called : Arguments : Return Values : */ #ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(flash_erase_bank, ".TI.ramfunc"); #endif Fapi_StatusType flash_erase_bank(uint32 *selected_bank_address, uint16_t sector_mask) { volatile Fapi_StatusType return_check = Fapi_Error_Fail; volatile Fapi_FlashStatusType flash_status; // GPIO_LED_G_SET(); return_check = Fapi_issueBankEraseCommand((uint32 *)selected_bank_address, sector_mask); flash_status = Fapi_getFsmStatus(); // GPIO_LED_G_CLEAR(); // Wait until FSM is done with bank erase operation while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady) { // // Initialize the Erase Pulses to zero after issuing max pulses // if(HWREG(FLASH0CTRL_BASE + FLASH_O_ACC_EP) > MAX_ERASE_PULSE) { EALLOW; // // Enable Flash Optimization // HWREG(FLASH0CTRL_BASE + FLASH_O_OPT) = OPT_ENABLE; HWREG(FLASH0CTRL_BASE + FLASH_O_ERA_PUL) = HWREG(FLASH0CTRL_BASE + FLASH_O_ERA_PUL) & ~(uint32_t)FLASH_ERA_PUL_MAX_ERA_PUL_M; // // Disable Flash Optimization // HWREG(FLASH0CTRL_BASE + FLASH_O_OPT) = OPT_DISABLE; EDIS; } } if(return_check != Fapi_Status_Success) { // Check Flash API documentation for possible errors // Example_Error(return_check); } // Read FMSTAT register contents to know the status of FSM after // erase command to see if there are any erase operation related errors flash_status = Fapi_getFsmStatus(); if(flash_status != 0) { // Check Flash API documentation for FMSTAT and debug accordingly // Fapi_getFsmStatus() function gives the FMSTAT register contents. // Check to see if any of the EV bit, ESUSP bit, CSTAT bit or // VOLTSTAT bit is set (Refer to API documentation for more details). // FMSTAT_Fail(); } return return_check; } /******************************************************************************/ /*-----------------------------Function Header--------------------------------*/ /******************************************************************************/ /* Function name : Function ID : Purpose of the function : Global Variables Referred : Global Variables Modified : Functions called : Arguments : Return Values : */ #ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(flash_erase_sector, ".TI.ramfunc"); #endif Fapi_StatusType flash_erase_sector(uint32_t bank_selected_address ) { Fapi_StatusType oReturnCheck; Fapi_FlashStatusType oFlashStatus; Fapi_FlashStatusWordType oFlashStatusWord; oReturnCheck = Fapi_issueAsyncCommand(Fapi_ClearMore); // // Wait until FSM is done with erase sector operation // // while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){} if(oReturnCheck != Fapi_Status_Success) { // // Check Flash API documentation for possible errors // // Example_Error(oReturnCheck); } // Erase Flash Bank0 sector7 oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)bank_selected_address); // Wait until FSM is done with erase sector operation while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){} if(oReturnCheck != Fapi_Status_Success) { // Check Flash API documentation for possible errors // Example_Error(oReturnCheck); } // Read FMSTAT register contents to know the status of FSM after // erase command to see if there are any erase operation related errors oFlashStatus = Fapi_getFsmStatus(); if(oFlashStatus != 0) { // Check Flash API documentation for FMSTAT and debug accordingly // Fapi_getFsmStatus() function gives the FMSTAT register contents. // Check to see if any of the EV bit, ESUSP bit, CSTAT bit or // VOLTSTAT bit is set (Refer to API documentation for more details). // FMSTAT_Fail(); } // Do blank check // Verify that Bank0 sector6 is erased. The Erase command itself does a verify as // it goes. Hence erase verify by CPU reads (Fapi_doBlankCheck()) is optional. oReturnCheck = Fapi_doBlankCheck((uint32 *)bank_selected_address, SECTOR_8KB_32_LENGTH, &oFlashStatusWord); if(oReturnCheck != Fapi_Status_Success) { // Check Flash API documentation for error info // Example_Error(oReturnCheck); } return oReturnCheck; } /******************************************************************************/ /*-----------------------------Function Header--------------------------------*/ /******************************************************************************/ /* Function name : Function ID : Purpose of the function : Global Variables Referred : Global Variables Modified : Functions called : Arguments : Return Values : */ #ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(flash_erase, ".TI.ramfunc"); #endif void flash_erase(void) { Fapi_StatusType return_check; Fapi_FlashStatusType flash_status; Fapi_FlashStatusWordType flash_status_word; // volatile uint32_t bank_selected_address = FLASH_BANK0_APP_SECTOR_START_ADDRESS; // return_check = flash_erase_bank((uint32_t *)FLASH_BANK0_APP_SECTOR_START_ADDRESS, FLASH_BANK0_BOOTLOADER_MASK); return_check = flash_erase_bank((uint32_t *)FLASH_BANK0_START_ADDRESS, FLASH_BANK0_BOOTLOADER_MASK); // flash_status = Fapi_getFsmStatus(); return_check = flash_erase_bank((uint32_t *)FLASH_BANK1_START_ADDRESS, (uint16_t)0); // flash_init(); // return_check = flash_erase_sector(0x91000); // while (bank_selected_address < FLASH_BANK1_END_ADDRESS) // { // return_check = flash_erase_sector(bank_selected_address); // if (Fapi_Status_Success == return_check) // { // GPIO_LED_G_SET(); // bank_selected_address += 0x1000u; // } // GPIO_LED_G_CLEAR(); // } // Do blank check // Verify that Bank0 sectors 6-15 and Bank 1 sectors 0-15 are erased. // The Erase command itself does a verify as it goes. // Hence erase verify by CPU reads (Fapi_doBlankCheck()) is optional. return_check = Fapi_doBlankCheck((uint32_t *)FLASH_BANK0_APP_SECTOR_START_ADDRESS, (26*SECTOR_8KB_32_LENGTH), &flash_status_word); if(return_check != Fapi_Status_Success) { // Check Flash API documentation for error info // Example_Error(return_check); GPIO_LED_G_SET(); } else { GPIO_LED_G_CLEAR(); } } /******************************************************************************/ /*-----------------------------Function Header--------------------------------*/ /******************************************************************************/ /* Function name : Function ID : Purpose of the function : Global Variables Referred : Global Variables Modified : Functions called : Arguments : Return Values : */ #ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(flash_program, ".TI.ramfunc"); #endif //****************************************************************************** // Program data into a bank in flash //****************************************************************************** Fapi_StatusType flash_program(uint16_t *buffer, uint32_t bank_selected_address, uint16_t data_length) { uint32_t u32Index = 0; uint16_t i = 0; Fapi_StatusType return_check; Fapi_FlashStatusType oFlashStatus; Fapi_FlashStatusWordType oFlashStatusWord; // A data buffer of max 8 16-bit words can be supplied to the program function. // Each word is programmed until the whole buffer is programmed or a // problem is found. However to program a buffer that has more than 8 // words, program function can be called in a loop to program 8 words for // each loop iteration until the whole buffer is programmed. // // Remember that the main array flash programming must be aligned to // 64-bit address boundaries and each 64 bit word may only be programmed // once per write/erase cycle. Meaning the length of the data buffer // (3rd parameter for Fapi_issueProgrammingCommand() function) passed // to the program function can only be either 4 or 8. // // Program data in Flash using "AutoEccGeneration" option. // When AutoEccGeneration opton is used, Flash API calculates ECC for the given // 64-bit data and programs it along with the 64-bit main array data. // Note that any unprovided data with in a 64-bit data slice // will be assumed as 1s for calculating ECC and will be programmed. // // Note that data buffer (program_buffer) is aligned on 64-bit boundary for verify reasons. // // Monitor ECC address for Bank0 Sector6 while programming with AutoEcc mode. // // In this example, 0xFF+1 bytes are programmed in Flash Bank0 Sector6 // along with auto-generated ECC. // // Fill a buffer with data to program into the flash. // int j = 0; for(i=0; i <= data_length/2; i++) { program_buffer[i] = (*(buffer+j+1) & 0xFF)|(*(buffer+j+0) << 8); j = j + 2; } for(i=0, u32Index = bank_selected_address; (u32Index < (bank_selected_address + (data_length/2))); i+= 8, u32Index+= 8) { return_check = Fapi_issueProgrammingCommand((uint32 *)u32Index, program_buffer+i, 8, 0, 0, Fapi_AutoEccGeneration); // Wait until the Flash program operation is over while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy); if(return_check != Fapi_Status_Success) { // Check Flash API documentation for possible errors // Example_Error(return_check); } // Read FMSTAT register contents to know the status of FSM after // program command to see if there are any program operation related errors oFlashStatus = Fapi_getFsmStatus(); if(oFlashStatus != 0) { //Check FMSTAT and debug accordingly // FMSTAT_Fail(); } // Verify the programmed values. Check for any ECC errors. // The program command itself does a verify as it goes. // Hence program verify by CPU reads (Fapi_doVerify()) is optional. return_check = Fapi_doVerify((uint32 *)u32Index, 4, program_buffer_ptr+(i/2), &oFlashStatusWord); if(return_check != Fapi_Status_Success) { // Check Flash API documentation for possible errors // Example_Error(return_check); } } return return_check; } /** @} */
The linker files for both bootloader project and application:
Bootloader:
/* //########################################################################### // // FILE: F280037_flash_lnk.cmd // // TITLE: Linker Command File For F280037 Device // //########################################################################### */ MEMORY { BOOT_RSVD : origin = 0x00000002, length = 0x00000126 RAMM0 : origin = 0x00000128, length = 0x000002D8 RAMM1 : origin = 0x00000400, length = 0x000003F8 /* on-chip RAM block M1 */ // RAMM1_RSVD : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ // RAMLS0 : origin = 0x00008000, length = 0x00000800 // RAMLS1 : origin = 0x00008800, length = 0x00000800 // RAMLS2 : origin = 0x00009000, length = 0x00000800 // RAMLS3 : origin = 0x00009800, length = 0x00000800 RAMLS03 : origin = 0x00008000, length = 0x00002000 RAMLS4 : origin = 0x0000A000, length = 0x00000800 RAMLS5_7 : origin = 0x0000A800, length = 0x00001800 // RAMLS6 : origin = 0x0000B000, length = 0x00000800 // RAMLS7 : origin = 0x0000B800, length = 0x00000800 /* Combining all the LS RAMs */ // RAMLS : origin = 0x00008000, length = 0x00004000 RAMGS0 : origin = 0x0000C000, length = 0x00001000 RAMGS1 : origin = 0x0000D000, length = 0x00001000 RAMGS2 : origin = 0x0000E000, length = 0x00001000 RAMGS3 : origin = 0x0000F000, length = 0x00000FF8 // RAMGS3_RSVD : origin = 0x000FFF8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ BOOTROM : origin = 0x003F8000, length = 0x00007FC0 SECURE_ROM : origin = 0x003F2000, length = 0x00006000 RESET : origin = 0x003FFFC0, length = 0x00000002 BEGIN : origin = 0x00080000, length = 0x00000002 FLASH_APP_CRC : origin = 0x00087000, length = 0x0000001F /* Flash sectors */ FLASH_BANK_BOOT : origin = 0x00080002, length = 0x00006FFE FLASH_BANK0_APP : origin = 0x00087022, length = 0x00008FDE FLASH_BANK1_APP : origin = 0x00090000, length = 0x0000FFF0 FLASH_BANK1_SEC15_DO_NOT_USE : origin = 0x09FFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ } SECTIONS { codestart : > BEGIN, ALIGN(8) .text : >> FLASH_BANK_BOOT, ALIGN(8) .cinit : > FLASH_BANK_BOOT, ALIGN(8) .switch : > FLASH_BANK_BOOT, ALIGN(8) .reset : > RESET, TYPE = DSECT /* not used, */ .stack : > RAMM1 .init_array : > FLASH_BANK_BOOT, ALIGN(8) .bss : > RAMLS5_7 .bss:output : > RAMLS03 .bss:cio : > RAMLS03 .data : > RAMLS5_7 .sysmem : > RAMLS5_7 .const : >> FLASH_BANK_BOOT, ALIGN(8) ramgs0 : > RAMGS0 ramgs1 : > RAMGS1 ramgs2 : > RAMGS2 ramgs3 : > RAMGS3 /* Allocate IQ math areas: */ IQmath : > RAMLS5_7 IQmathTables : > RAMLS5_7 DataBufferSection : > RAMGS0, ALIGN(8) GROUP { .TI.ramfunc { -l FAPI_F28003x_EABI_v1.58.10.lib} } LOAD = FLASH_BANK_BOOT, RUN = RAMLS03, LOAD_START(RamfuncsLoadStart), LOAD_SIZE(RamfuncsLoadSize), LOAD_END(RamfuncsLoadEnd), RUN_START(RamfuncsRunStart), RUN_SIZE(RamfuncsRunSize), RUN_END(RamfuncsRunEnd), ALIGN(8) /* crc/checksum section configured as COPY section to avoid including in executable */ .App_CodeStart : > FLASH_BANK0_APP, ALIGN(8) // Starting address of the app code .AppCode_CRCTable : > FLASH_APP_CRC // CRC table location } /* //########################################################################### // End of file. //########################################################################### */
Application:
/* //########################################################################### // // FILE: F280037_flash_lnk.cmd // // TITLE: Linker Command File For F280037 Device // //########################################################################### */ MEMORY { BOOT_RSVD : origin = 0x00000002, length = 0x00000126 RAMM0 : origin = 0x00000128, length = 0x000002D8 RAMM1 : origin = 0x00000400, length = 0x000003F8 /* on-chip RAM block M1 */ // RAMM1_RSVD : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ // RAMLS0 : origin = 0x00008000, length = 0x00000800 // RAMLS1 : origin = 0x00008800, length = 0x00000800 // RAMLS2 : origin = 0x00009000, length = 0x00000800 // RAMLS3 : origin = 0x00009800, length = 0x00000800 RAMLS03 : origin = 0x00008000, length = 0x00002000 RAMLS4 : origin = 0x0000A000, length = 0x00000800 RAMLS5_7 : origin = 0x0000A800, length = 0x00001800 // RAMLS6 : origin = 0x0000B000, length = 0x00000800 // RAMLS7 : origin = 0x0000B800, length = 0x00000800 /* Combining all the LS RAMs */ // RAMLS : origin = 0x00008000, length = 0x00004000 RAMGS0 : origin = 0x0000C000, length = 0x00001000 RAMGS1 : origin = 0x0000D000, length = 0x00001000 RAMGS2 : origin = 0x0000E000, length = 0x00001000 RAMGS3 : origin = 0x0000F000, length = 0x00000FF8 // RAMGS3_RSVD : origin = 0x000FFF8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ BOOTROM : origin = 0x003F8000, length = 0x00007FC0 SECURE_ROM : origin = 0x003F2000, length = 0x00006000 RESET : origin = 0x003FFFC0, length = 0x00000002 FLASH_APP_CRC : origin = 0x00087000, length = 0x0000001F BEGIN : origin = 0x00087020, length = 0x00000002 FLASH_BANK_BOOT : origin = 0x00080002, length = 0x00005FFE GROUP (FLASH_BANK0) { FLASH_BANK0_APP : origin = 0x00087022, length = 0x00008FDE } crc(_ccs_flash_bank0_checksum, algorithm=CRC8_PRIME) GROUP (FLASH_BANK1) { FLASH_BANK1_APP : origin = 0x00090000, length = 0x0000FFF0 } crc(_ccs_flash_bank1_checksum, algorithm=CRC8_PRIME) FLASH_BANK1_SEC15_DO_NOT_USE : origin = 0x09FFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */ } SECTIONS { codestart : > BEGIN, ALIGN(8) .text : >> FLASH_BANK0_APP, ALIGN(8) .cinit : > FLASH_BANK0_APP, ALIGN(8) .switch : > FLASH_BANK0_APP, ALIGN(8) .reset : > RESET, TYPE = DSECT /* not used, */ .stack : > RAMM1 .init_array : > FLASH_BANK0_APP, ALIGN(8) .bss : > RAMLS5_7 .bss:output : > RAMLS03 .bss:cio : > RAMLS03 .data : > RAMLS5_7 .sysmem : > RAMLS5_7 .const : >> FLASH_BANK0_APP, ALIGN(8) ramgs0 : > RAMGS0 ramgs1 : > RAMGS1 ramgs2 : > RAMGS2 ramgs3 : > RAMGS3 /* Allocate IQ math areas: */ IQmath : > RAMLS5_7 IQmathTables : > RAMLS5_7 .TI.ramfunc : LOAD = FLASH_BANK0_APP, RUN = RAMLS03, LOAD_START(RamfuncsLoadStart), LOAD_SIZE(RamfuncsLoadSize), LOAD_END(RamfuncsLoadEnd), RUN_START(RamfuncsRunStart), RUN_SIZE(RamfuncsRunSize), RUN_END(RamfuncsRunEnd), ALIGN(8) /* crc/checksum section configured as COPY section to avoid including in executable */ .TI.memcrc : > FLASH_APP_CRC } /* //########################################################################### // End of file. //########################################################################### */
Please let me know if Im missing something or why this is failing.
Regards,
Harsha