SPRUJ27C November 2022 – November 2023 TMS320F280033 , TMS320F280034 , TMS320F280034-Q1 , TMS320F280036-Q1 , TMS320F280036C-Q1 , TMS320F280037 , TMS320F280037-Q1 , TMS320F280037C , TMS320F280037C-Q1 , TMS320F280038-Q1 , TMS320F280038C-Q1 , TMS320F280039 , TMS320F280039-Q1 , TMS320F280039C , TMS320F280039C-Q1
Sets up data and issues program command to valid Flash or OTP memory addresses
Synopsis
Fapi_StatusType Fapi_issueProgrammingCommand(
uint32 *pu32StartAddress,
uint16 *pu16DataBuffer,
uint16 u16DataBufferSizeInWords,
uint16 *pu16EccBuffer,
uint16 u16EccBufferSizeInBytes,
Fapi_FlashProgrammingCommandType oMode)
Parameters
pu32StartAddress [in] | Start address in Flash for the data and ECC to be programmed | |
pu16DataBuffer [in] | Pointer to the Data buffer address. Data buffer should be 128-bit aligned. | |
u16DataBufferSizeInWords [in] | Number of 16-bit words in the Data buffer | |
pu16EccBuffer [in] | Pointer to the ECC buffer address | |
u16EccBufferSizeInBytes [in] | Number of 8-bit bytes in the ECC buffer | |
oMode [in] | Indicates the programming mode to use: | |
Fapi_DataOnly | Programs only the data buffer | |
Fapi_AutoEccGeneration | Programs the data buffer and auto generates and programs the ECC. | |
Fapi_DataAndEcc | Programs both the data and ECC buffers | |
Fapi_EccOnly | Programs only the ECC buffer |
Description
This function sets up the programming registers of the Flash State Machine based on the supplied parameters. It offers four different programming modes to the user for use in different scenarios as mentioned in Table 3-1.
Programming Mode (oMode) | Arguments Used | Usage Purpose |
---|---|---|
Fapi_DataOnly | pu32StartAddress, pu16DataBuffer, u16DataBufferSizeInWords | Used when any custom programming utility or an user application (that embed/use Flash API) has to program data and corresponding ECC separately. Data is programmed using Fapi_DataOnly mode and then the ECC is programmed using Fapi_EccOnly mode. Generally most of the programming utilities do not calculate ECC separately and instead use Fapi_AutoEccGeneration mode. However, some Safety applications may require to insert intentional ECC errors in their Flash image (which is not possible when Fapi_AutoEccGeneration mode is used) to check the health of the SECDED (Single Error Correction and Double Error Detection) module at run time. In such case, ECC is calculated separately (using either the ECC calculation algorithm provided in Appendix F or using the Fapi_calculateEcc() function as applicable). Application may want to insert errors in either main array data or in the ECC as needed. In such scenarios, after the error insertion, Fapi_DataOnly mode and Fapi_EccOnly modes can be used to program the data and ECC respectively. |
Fapi_AutoEccGeneration | pu32StartAddress, pu16DataBuffer, u16DataBufferSizeInWords | Used when any custom programming utility or user application (that embed/use Flash API to program Flash at run time to store data or to do a firmware update) has to program data and ECC together without inserting any intentional errors. This is the most prominently used mode. |
Fapi_DataAndEcc | pu32StartAddress, pu16DataBuffer, u16DataBufferSizeInWords, pu16EccBuffer, u16EccBufferSizeInBytes | Purpose of this mode is not different than that of using Fapi_DataOnly and Fapi_EccOnly modes together. However, this mode is beneficial when both the data and the calculated ECC can be programmed at the same time. |
Fapi_EccOnly | pu16EccBuffer, u16EccBufferSizeInBytes | See the usage purpose given for Fapi_DataOnly mode. |
Programming modes:
Fapi_DataOnly – This mode will only program the data portion in Flash at the address specified. It can program from 1-bit up to 8 16-bit words. However, review the restrictions provided for this function to know the limitations of flash programming data size. The supplied starting address to program at plus the data buffer length cannot cross the 128-bit aligned address boundary. Arguments 4 and 5 are ignored when using this mode.
Fapi_AutoEccGeneration – This mode will program the supplied data in Flash along with automatically generated ECC. The ECC is calculated for every 64-bit data aligned on a 64-bit memory boundary. Hence, when using this mode, all the 64 bits of the data should be programmed at the same time for a given 64-bit aligned memory address. Data not supplied is treated as all 1s (0xFFFF). Once ECC is calculated and programmed for a 64-bit data, those 64 bits can not be reprogrammed (unless the sector is erased) even if it is programming a bit from 1 to 0 in that 64-bit data, since the new ECC value will collide with the previously programmed ECC value. When using this mode, if the start address is 128-bit aligned, then either 8 or 4 16-bit words can 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 can be programmed at the same time. The data restrictions for Fapi_DataOnly also exist for this option. Arguments 4 and 5 are ignored
Here is an example:
SECTIONS
{
.text : > FLASH, ALIGN(4)
.cinit : > FLASH, ALIGN(4)
.const : > FLASH, ALIGN(4)
.init_array : > FLASH, ALIGN(4)
.switch : > FLASH, ALIGN(4)
}
If you do not align the sections in flash, you would need to track incomplete 64-bit words in a section and combine them with the words in other sections that complete the 64-bit word. This will be difficult to do. So it is recommended to align your sections on 64-bit boundaries.
Some 3rd party Flash programming tools or TI Flash programming kernel examples (C2000Ware) or any custom Flash programming solution may assume that the incoming data stream is all 128-bit aligned and may not expect that a section might start on an unaligned address. Thus it may try to program the maximum possible (128-bits) words at a time assuming that the address provided is 128-bit aligned. This can result in a failure when the address is not aligned. So, it is suggested to align all the sections (mapped to Flash) on a 128-bit boundary using ALIGN(8).
Fapi_DataAndEcc – This mode will program both the supplied data and ECC in Flash at the address specified. The data supplied must be aligned on a 64-bit memory boundary and the length of data must correlate to the supplied ECC. That means, if the data buffer length is 4 16-bit words, the ECC buffer must be 1 byte. If the data buffer length is 8 16-bit words, the ECC buffer must be 2 bytes in length. If the 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.
The LSB of pu16EccBuffer corresponds to the lower 64-bits of the main array and the MSB of pu16EccBuffer corresponds to the upper 64-bits of the main array.
The Fapi_calculateEcc() function can be used to calculate ECC for a given 64-bit aligned address and the corresponding data.
Fapi_EccOnly – This mode will only program the ECC portion in Flash ECC memory space at the address (Flash main array address should be provided for this function and not the corresponding ECC address) specified. It can program either 2 bytes (both LSB and MSB at a location in ECC memory) or 1 byte (LSB at a location in ECC memory).
The LSB of pu16EccBuffer corresponds to the lower 64-bits of the main array and the MSB of pu16EccBuffer corresponds to the upper 64-bits of the main array.
Arguments two and three are ignored when using this mode.
Also, the user application should use the Fapi_doVerify() function to verify that the Flash is programmed correctly.
This function does not wait until the program operation is over; it just issues the command and returns back. Hence, the user application must wait for the FMC to complete the program operation before returning to any kind of Flash accesses. The Fapi_checkFsmForReady() function should be used to monitor the status of an issued command.
Restrictions
Return Value
Sample Implementation
This example does not show the erase operation. Note that a sector should be erased before it can be reprogrammed.
#include “F021_F28003x_C28x.h”
#define CPUCLK_FREQUENCY 120 /* 120 MHz System frequency */
int main(void)
{
//
// Initialize System Control
//
Device_init();
//
// Call Flash Initialization to setup flash waitstates
// This function must reside in RAM
//
Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES);
//
// Jump to RAM and call the Flash API functions
//
Example_CallFlashAPI();
}
#pragma CODE_SECTION(Example_CallFlashAPI, ramFuncSection);
void Example_CallFlashAPI(void)
{
Fapi_StatusType oReturnCheck;
Fapi_FlashStatusType oFlashStatus;
uint16 au16DataBuffer[8] = {0x0001, 0x0203, 0x0405, 0x0607, 0x0809, 0x0A0B, 0x0C0D, 0x0E0F};
uint32 *DataBuffer32 = (uint32 *)au16DataBuffer;
uint32 u32Index = 0;
EALLOW;
//
// This function is required to initialize the Flash API based on
// System frequency before any other Flash API operation can be performed
// Note that the FMC register base address and system frequency are passed as the parameters
//
oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, CPUCLK_FREQUENCY);
if(oReturnCheck != Fapi_Status_Success)
{
Example_Error(oReturnCheck);
}
//
// Fapi_setActiveFlashBank function initializes Flash banks
// and FMC for erase and program operations.
//
oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
if(oReturnCheck != Fapi_Status_Success)
{
Example_Error(oReturnCheck);
}
//
// Bank0 Program
//
//
// Program 0x200 16-bit words in Bank0 Sector 4
//
for(u32Index = 0x84000; (u32Index < 0x84200) &&
(oReturnCheck == Fapi_Status_Success); u32Index+=8)
{
//
// Issue program command
//
oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index, au16DataBuffer, 8,
0, 0, Fapi_AutoEccGeneration);
//
// Wait until the Flash program operation is over
//
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
if(oReturnCheck != Fapi_Status_Success)
{
Example_Error (oReturnCheck);
}
//
// 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
//
oReturnCheck = Fapi_doVerify((uint32 *)u32Index, 4, DataBuffer32, &oFlashStatusWord);
if(oReturnCheck != Fapi_Status_Success)
{
//
// Check Flash API documentation for possible errors
//
Example_Error(oReturnCheck);
}
}
//
// * User code for further Bank0 flash operations *
//
.
.
.
.
//
// Example is done here
//
Example_Done();
}