第一章 获取相关组件(注意:下载或安装不要有中文路径)
第二章 新建工程(注意:代码移植时,索引路径需要重新设置(绝对地址))
… …
第N章 Bootloader(TMS320F28004x Flash API Reference Guide)的学习
本文章采用CCS10.3.1(CCS软件版本)及C2000Ware_4_01(SDK-设计资源)进行TMS320F280049(DSP芯片)系列学习
parameter_1 [in] Type details of parameter_1
parameter_2 [out] Type details of parameter_2
parameter_n [in/out] Type details of parameter_3
注:请阅读Flash和OTP内存映射和Flash等待状态的数据手册规格说明书
API函数 | 描述 |
---|---|
Fapi_initializeAPI() | 初次使用或频率更改初始化API |
API函数 | 描述 |
---|---|
Fapi_setActiveFlashBank() | 初始化Flash存储控制器(FMC)和块的擦除和程序命令 |
Fapi_issueAsyncCommandWithAddress() | 针对给定的地址向FSM发出擦除扇区命令 |
Fapi_issueProgrammingCommand() | 设置编程所需的寄存器,并向FSM发出该命令 |
Fapi_issueProgrammingCommandForEccAddress() | 将一个ECC地址重新映射到主数据空间,然后调用Fapi_issueProgrammingCommand()来编程ECC |
Fapi_issueFsmSuspendCommand() | 暂停FSM命令、程序数据和擦除扇区 |
Fapi_issueAsyncCommand() | 针对不需要地址的操作,向FSM发出命令(清除状态、程序恢复、删除恢复、清除更多) |
Fapi_checkFsmForReady() | 返回Flash状态机(FSM)是否准备就绪或是否繁忙 |
Fapi_getFsmStatus() | 从Flash存储控制器返回FMSTAT状态寄存器值 |
API函数 | 描述 |
---|---|
Fapi_doBlankCheck() | 根据已擦除的状态验证指定的Flash存储范围 |
Fapi_doVerify() | 根据提供的值验证指定的Flash存储范围 |
Fapi_calculatePsa() | 计算指定Flash存储范围的PSA值 |
Fapi_doPsaVerify() | 根据提供的PSA值验证指定的Flash存储范围 |
API函数 | 描述 |
---|---|
Fapi_getLibraryInfo() | 返回特定于API库的已编译版本的信息 |
API函数 | 描述 |
---|---|
Fapi_flushPipeline() | 刷新FMC中的数句缓存 |
Fapi_calculateEcc() | 计算所提供的地址和64位的ECC |
Fapi_isAddressEcc() | 确定该地址是否落在ECC范围内 |
Fapi_remapEccAddress() | 将ECC地址重新映射到相应的主地址 |
Fapi_calculateFletcherChecksum() | 函数计算指定的内存范围的Fletcher校验和 |
注:
Fapi_getDeviceInfo()和Fapi_getBankSectors()在TMS320F28004x Flash API中已被删除,因为用户可以获得这些信息(例如:bank数、pin数、扇区数等等,从TRM中提供的其他资源)
不再提供Fapi_UserDefinedFunctions.c文件,因为该文件中的函数现在合并在Flash API库中(有关使用Flash API时维护看门狗服务的信息,请查看第2.3.3节)
注:编译需要启用“启用对GCC扩展的支持”选项(编译器6.4.0及以上版本默认启用此选项)
以下API文件分布在C2000Warelibrariesflash_apif28004x文件夹中:
Library文件
• TMS320F28004x Flash API被嵌入到该设备的引导ROM中。这不同于其他API的C28x设备中完全是软件。
• 提供了一个软件库(F021_API_F28004x_FPU32.lib)和一个BootROM API符号库(F021_ROM_API_F28004x_FPU32.lib)
• 为了使应用程序能够删除或编写Flash/OTP,这两个库文件中的一个应该包含在应用程序中符号库的优先项
Include文件
• F021_F28004x_C28xh:主文件包括TMS320F28004x设备。此文件设置特定于编译的定义,包含F021.h主文件包含文件
以下包括的文件不应该直接包含在用户的代码中,但在这里列出以供用户参考:
• F021.h:包括文件列出所有公共API函数,并包括所有其他包括文件
• Init.h:定义API初始化结构
• Registers_C28x.h:小端闪存控制器寄存器结构
• Registers.h:所有寄存器实现通用的定义,包括适当的寄存器,包括所选设备类型的文件
• type.h:包含API使用的所有枚举和结构
• Constants/Constants.h:一些C2000设备常见的常数定义
• Constants/F28004x.h:F28004x器件的常数定义
//
// Erase a Sector
//
oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,(uint32*)0x0080000);
//
// Wait until the erase operation is over
//
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}
• Flash API不配置(启用/禁用)看门狗。用户应用程序可以配置看门狗,并根据需要为其提供服务。因此,不再提供Fapi_ServiceWatchdogTimer()函数
• Flash API在内部使用EALLOW和EDIS来允许/不允许写入受保护的寄存器
• 主阵列闪存编程必须与64位地址边界对齐,并且在每个写/删除周期中,每个64位字只能被编程一次
• 允许对数据和ECC分别进行编程。然而,每个64位数据字和16位ECC字在每次写入/擦除周期中只能被编程一次
• DCSM OTP编程必须与128位地址边界对齐,每个128位字只能编程一次。例外情况是:-DCSM OTP中的DCSM Zx-LINKPOINTER1和Zx-LINKPOINTER2的值应该一起编程,并且可以根据DCSM操作的要求一次编程1位。–DCSM OTP中的DCSM Zx-LINKPOINTER3值可以在64位边界上一次编程1位,以将其与Zx-脉冲交换锁分离,后者只能编程一次
• TMS320F28004x设备中没有泵浦信号量
• 不应该为链接指针的位置编程ECC。当为程序操作提供的起始地址是三个链接指针地址中的任何一个时,API就会跳过对ECC进行编程。API将使用Fapi_DataOnly模式来编程这些位置,即使用户将Fapi_AutoEccGeneration或Fapi_DataAndEcc模式作为编程模式参数。不支持编程这些位置的Fapi_EccOnly模式。用户应用程序在这里应该谨慎行事。应注意为应用程序中的链接指针位置维护一个单独的结构/部分。不要将这些字段与其他DCSM OTP设置混合。如果其他字段与链接指针混合,API也会跳过针对非链接指针位置的编程ECC。这将导致应用程序中的ECC错误
• 当使用INTOSC作为时钟源时,一些SYSCLK频率范围需要一个额外的等待状态来执行擦除和程序操作。操作结束后,不需要额外的等待状态。详情请参考数据手册
• 为了避免区域1和区域2之间的冲突,在DCSM寄存器中提供了一个信号量(FLSEM)来配置Flash寄存器。用户应用程序应该在初始化Flash和调用Flash API函数之前配置这个信号量寄存器。详情请参考TMS320F28004x短笛微控制器技术参考手册
• 请注意,Flash API函数不配置任何DCSM寄存器。用户应用程序应该确保配置所需的DCSM设置。例如,如果一个区域是安全的,那么应该从同一区域执行Flash API,以便能够擦除或编程该区域的Flash扇区。或者这个区域应该被解锁。如果没有,FlashAPI写入Flash寄存器将不会成功。Flash API不检查对Flash寄存器的写入是否正在完成。它按照擦除/程序序列的需要写入它们,并在写入完成后返回。这将导致Flash API返回错误的成功状态。例如,调用Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,Adderes)时可以返回成功状态,但这并不意味着扇区擦除成功。应该使用Fapi_getFSMStatus()和Fapi_doBlankCheck()来检查清除状态
• Flash API已嵌入到此设备的ROM中。为了在ROM中使用Flash API,用户必须在C2000Ware_x_xx_xx_xxlibrariesflash_apif28004xlib.中嵌入C2000Ware中提供的F021_ROM_API_F28004x_FPU32.lib(ROM API符号)库当使用ROM API时,不需要将F021_API_F28004x_FPU32.lib(软件API)嵌入到应用程序中以实现Flash擦除/程序的目的。当使用ROM API时,请确保不要在链接器命令文件中为API库分配flash加载地址和ram运行地址,因为它已经存在于ROM中。但是,任何调用Flash API函数的应用程序函数必须从RAM(单个银行设备)或没有针对闪存删除/程序操作的其他银行(双银行设备)执行。还要注意,不应该有任何访问正在进行闪存擦除/程序操作的闪存库/OTP的权限
注:在调用此函数之前,必须设置RWAIT寄存器值
#include “F021_F28004x_C28x.h”
#define CPUCLK_FREQUENCY 100 /* 100 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;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, 100);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// Fapi_setActiveFlashBank function initializes Flash banks// and FMC for erase and program operations.// Note: It does not matter which bank is passed as the parameter to initialize.// Both Banks and FMC get initialized with one function call unlike F2837xS.// Hence, there is no need to execute Fapi_setActiveFlashBank() for each bank.//oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// Bank0 Erase Program///* User code for further Bank0 flash operations */....//// Bank1 Erase Program////// There is no need to call Fapi_initializeAPI() and Fapi_setActiveFlashBank()// when switching to Bank1 Flash operations///* User code for further Bank1 flash operations */....EDIS;//// Example is done here//Example_Done();
}
注:
此函数在发出erase命令后不检查FMSTAT。当FSM完成了擦除操作时,用户应用程序必须检查FMSTAT值。FMSTAT表示在擦除操作过程中是否出现了任何故障。用户应用程序可以使用Fapi_getFSMStatus函数来获取FMSTAT值。此外,用户应用程序应该使用Fapi_doBlankCheck()功能来验证Flash是否被删除
#include “F021_F28004x_C28x.h”
#define CPUCLK_FREQUENCY 100 /* 100 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;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, 100);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// Fapi_setActiveFlashBank function initializes Flash banks// and FMC for erase and program operations.// Note: It does not matter which bank is passed as the parameter to initialize.// Both Banks and FMC get initialized with one function call unlike F2837xS.// Hence, there is no need to execute Fapi_setActiveFlashBank() for each bank.//oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// Bank0 Flash operations////// Erase Bank0 Sector4//oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)0x84000);//// Wait until FSM is done with erase sector operation//while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady){}if (oReturnCheck != Fapi_Status_Success){Example_Error (oReturnCheck);}//// Read FMSTAT 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){FMSTAT_Fail();}//// Do blank check.// Verify that the sector is erased.//oReturnCheck = Fapi_doBlankCheck((uint32 *)0x84000, 0x800, &oFlashStatusWord);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// * User code for further Bank0 flash operations *//....//// Bank1 Flash operations////// There is no need to call Fapi_initializeAPI() and Fapi_setActiveFlashBank()// when switching to Bank1 Flash operations////// Erase Bank1 Sector2//oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32 *)0x92000);//// Wait until FSM is done with erase sector operation//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 erase command to see if there are any erase operation// related errors//oFlashStatus = Fapi_getFsmStatus();if (oFlashStatus != 0){FMSTAT_Fail();}//// Do blank check.// Verify that the sector is erased.//oReturnCheck = Fapi_doBlankCheck((uint32 *)0x92000, 0x800, &oFlashStatusWord);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// * User code for further Bank1 flash operations *//....EDIS;//// Example is done here//Example_Done();
}
注:
pu16EccBuffer应包含与128位对齐的主阵列/OTP地址处的数据相对应的ECC。pu16体外缓冲器的LSB对应于主阵列的下64位,而pu16体外缓冲器的MSB对应于主阵列的上64位
编程模式(oMode) | 使用的参数 | 使用目的 |
---|---|---|
Fapi_DataOnly | pu32StartAddress, pu16DataBuffer, u16DataBufferSizeInWords | 当任何自定义编程实用程序或用户应用程序(嵌入/使用Flash API)必须分别对数据和相应的ECC进行编程时使用。数据使用Fapi_DataOnly模式进行编程,然后使用Fapi_EccOnly模式进行编程的ECC。通常,大多数编程实用程序并不单独计算ECC,而是使用Fapi_AutoEccGeneration模式。然而,一些安全应用程序可能需要在其Flash映像中插入有意的ECC错误(使用Fapi_AutoEccGeneration模式时不可能),以在运行时检查SECDED(单错误纠正和双错误检测)模块的运行状况。在这种情况下,ECC是单独计算的(使用附录E中提供的ECC计算算法或在适用时使用Fapi_calculateEcc()函数)。应用程序可能希望根据需要在主阵列数据或ECC中插入错误。在这种情况下,在错误插入后,可以使用Fapi_DataOnly模式和Fapi_EccOnly模式分别对数据和ECC进行编程 |
Fapi_AutoEccGeneration | pu32StartAddress, pu16DataBuffer, u16DataBufferSizeInWords | 当任何自定义编程实用程序或用户应用程序(嵌入/使用Flash API在运行时编写Flash以存储数据或执行固件更新)必须将数据和ECC一起编写程序而不插入任何有意的错误时使用。这是最显著使用的模式 |
Fapi_DataAndEcc | pu32StartAddress, pu16DataBuffer, u16DataBufferSizeInWords, pu16EccBuffer, u16EccBufferSizeInBytes | 该模式的目的与同时使用Fapi_DataOnly模式和Fap_EccOnly模式并没有什么不同。但是,当数据和计算出的ECC可以同时进行编程时,这种模式是有益的 |
Fapi_EccOnly | pu16EccBuffer, u16EccBufferSizeInBytes | 请参阅针对Fapi_DataOnly模式给出的使用目的 |
注:用户必须始终为他们的Flash编程ECC,因为ECC检查是在通电时启用的
注:
Fapi_AutoEccGeneration模式将在Flash中编程所提供的数据部分以及自动生成的ECC。对64位对齐的地址和相应的64位数据计算ECC。未提供的任何数据都将被视为0x FFFF。请注意,当编写一个自定义编程实用程序,该程序在代码项目的输出文件中流,并将每个部分一次编写到flash时,这具有实际意义。如果一个64位字跨越多个部分(即包含一个部分的结束和另一个部分的开始),那么在编程第一个部分时,不能假设64位字中缺失的数据值为0x FFFF。当您去编程第二部分时,您将无法为第一个64位字的ECC进行编程,因为它已经(错误地)使用假设的0x FFFF对缺失的值进行了计算和编程。避免此问题的一种方法是在代码项目的链接器命令文件中的64位边界上对齐链接到flash的所有部分
下面是一个示例:
SECTIONS
{.text : > FLASH, PAGE = 0, ALIGN(4).cinit : > FLASH, PAGE = 0, ALIGN(4).const : > FLASH, PAGE = 0, ALIGN(4).econst : > FLASH, PAGE = 0, ALIGN(4).pinit : > FLASH, PAGE = 0, ALIGN(4).switch : > FLASH, PAGE = 0, ALIGN(4)
}
如果不在flash中对齐这些部分,则需要跟踪一个部分中不完整的64位单词,并将它们与完成64位单词的其他部分中的单词结合起来。这将是很难做到的。因此,建议在64位边界上对齐您的部分
注:
pu16数据缓冲和pu16Ecc缓冲的长度不能超过8和2
此函数在发出程序命令后不检查FMSTAT。当FSM完成程序操作时,用户应用程序必须检查FMSTAT值。FMSTAT表示在程序操作过程中是否出现了任何故障。用户应用程序可以使用Fapi_getFsmStatus函数来获取FMSTAT值。此外,用户应用程序应该使用Fapi_doVerify()功能来验证Flash程序是否正确编程
#include “F021_F28004x_C28x.h”
#define CPUCLK_FREQUENCY 100 /* 100 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, 100);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// Fapi_setActiveFlashBank function initializes Flash banks// and FMC for erase and program operations.// Note: It does not matter which bank is passed as the parameter to initialize.// Both Banks and FMC get initialized with one function call unlike F2837xS.// Hence, there is no need to execute Fapi_setActiveFlashBank() for each bank.//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 *//....//// Bank1 Program////// There is no need to call Fapi_initializeAPI() and Fapi_setActiveFlashBank()// when switching to Bank1 Flash operations////// Program 0x200 16-bit words in Bank1 Sector 2//for(u32Index = 0x92000; (u32Index < 0x92200) && (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 Bank1 flash operations *//....EDIS;//// Example is done here//Example_Done();
}
注:
pu16ec缓冲器的长度不能超过2
此函数在发出程序命令后不检查FMSTAT。当FSM完成程序操作时,用户应用程序必须检查FMSTAT值。FMSTAT表示在程序操作过程中是否出现了任何故障。用户应用程序可以使用Fapi_getFSMStatus函数来获取FMSTAT值
注:
此函数在发出该命令后不检查FMSTAT。当FSM完成操作时,用户应用程序必须检查FMSTAT值。FMSTAT表示在操作过程中是否出现了任何故障。用户应用程序可以使用Fapi_getFsmStatus函数来获取FMSTAT值
#include “F021_F28004x_C28x.h”
#define CPUCLK_FREQUENCY 100 /* 100 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;//// Bank0 operations//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, 100);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// Fapi_setActiveFlashBank function initializes Flash banks// and FMC for erase and program operations.// Note: It does not matter which bank is passed as the parameter to initialize.// Both Banks and FMC get initialized with one function call unlike F2837xS.// Hence, there is no need to execute Fapi_setActiveFlashBank() for each bank.//oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);if (oReturnCheck != Fapi_Status_Success){Example_Error(oReturnCheck);}//// Issue an async command//oReturnCheck = Fapi_issueAsyncCommand(Fapi_ClearMore);//// Wait until the Fapi_ClearMore 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();}//// * User code for further Bank0 and Bank1 flash operations *//....EDIS;//// Example is done here//Example_Done();
}
#if defined(__TMS320C28XX__)
typedef unsigned char boolean;
typedef unsigned int uint8; /*This is 16 bits in C28x*/
typedef unsigned int uint16;
typedef unsigned long int uint32;
typedef unsigned long long int uint64;
typedef unsigned int uint16_least;
typedef unsigned long int uint32_least;
typedef signed int sint16_least;
typedef signed long int sint32_least;
#else
typedef unsigned char boolean;
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef unsigned long long int uint64;
typedef signed char sint8;
typedef signed short sint16;
typedef signed int sint32;
typedef signed long long int sint64;
typedef unsigned int uint8_least;
typedef unsigned int uint16_least;
typedef unsigned int uint32_least;
typedef signed int sint8_least;
typedef signed int sint16_least;
typedef signed int sint32_least;
typedef float float32;
typedef double float64;
#endif
#if (defined(__TMS320C28xx__) && __TI_COMPILER_VERSION__ < 6004000)
#if !defined(__GNUC__)
#error “F021 Flash API requires GCC language extensions. Use the –gcc option.”
#endif
#endif#ifndef TRUE
#define TRUE 1
#endif#ifndef FALSE
#define FALSE 0
#endif
typedef enum
{Cpu_ARM7,Cpu_M3,Cpu_R4,Cpu_R4F,Cpu_C28,Cpu_Undefined
} ATTRIBUTE_PACKED Fapi_CpuType;
typedef enum
{Fapi_AutoEccGeneration, /* Command will autogenerate the ecc for the provided data buffer */Fapi_DataOnly, /* Command will only process the data buffer */Fapi_EccOnly, /* Command will only process the ecc buffer */Fapi_DataAndEcc /* Command will process data and ecc buffers */
} ATTRIBUTE_PACKED Fapi_FlashProgrammingCommandsType;
typedef enum
{Fapi_FlashBank0,Fapi_FlashBank1, /*Not used in TMS320F28004x Flash API*/Fapi_FlashBank2, /*Not used in TMS320F28004x Flash API*/Fapi_FlashBank3, /*Not used in TMS320F28004x Flash API*/Fapi_FlashBank4, /*Not used in TMS320F28004x Flash API*/Fapi_FlashBank5, /*Not used in TMS320F28004x Flash API*/Fapi_FlashBank6, /*Not used in TMS320F28004x Flash API*/Fapi_FlashBank7 /*Not used in TMS320F28004x Flash API*/
} ATTRIBUTE_PACKED Fapi_FlashBankType;
typedef enum
{Fapi_ProgramData = 0x0002,Fapi_EraseSector = 0x0006,Fapi_EraseBank = 0x0008, /*Not available in TMS320F28004x devices */Fapi_ValidateSector = 0x000E, /*Not available in TMS320F28004x devices */Fapi_ClearStatus = 0x0010,Fapi_ProgramResume = 0x0014,Fapi_EraseResume = 0x0016,Fapi_ClearMore = 0x0018
} ATTRIBUTE_PACKED Fapi_FlashStateCommandsType;
typedef enum
{Fapi_NormalRead = 0x0,Fapi_RM0 = 0x1, /*Technology used in TMS320F28004x does not need this*/Fapi_RM1 = 0x2 /*Technology used in TMS320F28004x does not need this*/
} ATTRIBUTE_PACKED Fapi_FlashReadMarginModeType;
typedef enum
{Fapi_Status_Success=0, /* Function completed successfully */Fapi_Status_FsmBusy, /* FSM is Busy */Fapi_Status_FsmReady, /* FSM is Ready */Fapi_Status_AsyncBusy, /* Async function operation is Busy */Fapi_Status_AsyncComplete, /* Async function operation is Complete */Fapi_Error_Fail = 500, /* Generic Function Fail code */Fapi_Error_StateMachineTimeout, /* State machine polling never returned ready and timed out */Fapi_Error_OtpChecksumMismatch, /* Returned if OTP checksum does not match expected value */Fapi_Error_InvalidDelayValue, /* Returned if the Calculated RWAIT value exceeds 15 - Legacy Error */Fapi_Error_InvalidHclkValue, /* Returned if FClk is above max FClk value - FClk is a calculated from SYSCLK and RWAIT */Fapi_Error_InvalidCpu, /* Returned if the specified Cpu does not exist */Fapi_Error_InvalidBank, /* Returned if the specified bank does not exist */Fapi_Error_InvalidAddress, /* Returned if the specified Address does not exist in Flash or OTP */Fapi_Error_InvalidReadMode, /* Returned if the specified read mode does not exist */Fapi_Error_AsyncIncorrectDataBufferLength,Fapi_Error_AsyncIncorrectEccBufferLength,Fapi_Error_AsyncDataEccBufferLengthMismatch,Fapi_Error_FeatureNotAvailable, /* FMC feature is not available on this device */Fapi_Error_FlashRegsNotWritable /* Returned if Flash registers are not writable due to security */
} ATTRIBUTE_PACKED Fapi_StatusType;
typedef enum
{Alpha_Internal, /* For internal TI use only. Not intended to be used by customers */Alpha, /* Early Engineering release. May not be functionally complete */Beta_Internal, /* For internal TI use only. Not intended to be used by customers */Beta, /* Functionally complete, to be used for testing and validation */Production /* Fully validated, functionally complete, ready for production use */
} ATTRIBUTE_PACKED Fapi_ApiProductionStatusType;
typedef struct
{uint32 au32StatusWord[4];
} ATTRIBUTE_PACKED Fapi_FlashStatusWordType;
typedef struct
{uint8 u8ApiMajorVersion;uint8 u8ApiMinorVersion;uint8 u8ApiRevision;Fapi_ApiProductionStatusType oApiProductionStatus;uint32 u32ApiBuildNumber;uint8 u8ApiTechnologyType;uint8 u8ApiTechnologyRevision;uint8 u8ApiEndianness;uint32 u32ApiCompilerVersion;
} Fapi_LibraryInfoType;
f(X) = 1 + X + X^2 + X^22 + X^31uint32 calculatePSA (uint32* pu32StartAddress, uint32 u32Length, /* Number of 32-bit words */ uint32 u32InitialSeed)
{uint32 u32Seed, u32SeedTemp;u32Seed = u32InitialSeed;while (u32Length--){u32SeedTemp = (u32Seed << 1) ^ *(pu32StartAddress++);if (u32Seed & 0x80000000){u32SeedTemp ^= 0x00400007; /* XOR the seed value with mask */}u32Seed = u32SeedTemp;} return u32Seed;
}
//
//Calculate the ECC for an address/data pair
//
uint16 CalcEcc(uint32 address, uint64 data)
{const uint32 addrSyndrome[8] = {0x554ea, 0x0bad1, 0x2a9b5, 0x6a78d, 0x19f83, 0x07f80, 0x7ff80, 0x0007f};const uint64 dataSyndrome[8] = {0xb4d1b4d14b2e4b2e, 0x1557155715571557, 0xa699a699a699a699, 0x38e338e338e338e3, 0xc0fcc0fcc0fcc0fc, 0xff00ff00ff00ff00, 0xff0000ffff0000ff, 0x00ffff00ff0000ff};const uint16 parity = 0xfc;uint64 xorData;uint32 xorAddr;uint16 bit, eccBit, eccVal;////Extract bits "20:2" of the address//address = (address >> 2) & 0x7ffff;////Compute the ECC one bit at a time.//eccVal = 0;for (bit = 0; bit < 8; bit++){////Apply the encoding masks to the address and data//xorAddr = address & addrSyndrome[bit];xorData = data & dataSyndrome[bit];////Fold the masked address into a single bit for parity calculation.//The result will be in the LSB.//xorAddr = xorAddr ^ (xorAddr >> 16);xorAddr = xorAddr ^ (xorAddr >> 8);xorAddr = xorAddr ^ (xorAddr >> 4);xorAddr = xorAddr ^ (xorAddr >> 2);xorAddr = xorAddr ^ (xorAddr >> 1);////Fold the masked data into a single bit for parity calculation.//The result will be in the LSB.//xorData = xorData ^ (xorData >> 32);xorData = xorData ^ (xorData >> 16);xorData = xorData ^ (xorData >> 8);xorData = xorData ^ (xorData >> 4);xorData = xorData ^ (xorData >> 2);xorData = xorData ^ (xorData >> 1);////Merge the address and data, extract the ECC bit, and add it in//eccBit = ((uint16)xorData ^ (uint16)xorAddr) & 0x0001;eccVal |= eccBit << bit;}////Handle the bit parity. For odd parity, XOR the bit with 1//eccVal ^= parity;return eccVal;
}
本章为TMS320F280049学习系列文章 第N章:Bootloader(TMS320F28004x Flash API Reference Guide)的学习
本文发布于:2024-01-31 18:27:12,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170669683430488.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |