TMS320F280049 Flash/OTP
下文主要记录调用TI Flash API静态库和User OTP准备工作下载安装C2000Ware下载安装CCS软件可以从TI官网下载,下载安装不做说明。CCS创建工程添加Flash API静态库与头文件flash api:擦除编程校验地址边界对齐:flashotp生成hex文件修改CMD文件......
下文主要记录调用TI Flash API静态库和User OTP
一、准备工作
- 下载安装C2000Ware
- 下载安装CCS(Code Composer Studio 10.4.0)
软件可以从TI官网下载,下载安装不做说明。
二、CCS创建工程
1.Project------>>New CCS Project…
2.选择芯片型号
3.选择仿真器(根据实际情况选择)
后续可以在ccxml文件中修改
4.输入工程名
5.选择XXX.cmd文件。
xxx_FLASH_lnk.cmd:编译出的代码在flash区
xxx_RAM_lnk.cmd:编译出的代码在RAM区
本次代码要放在RAM区运行,所以选择280049_RAM_lnk.cmd。
6.选择 Empty Project(with main.c)
7.其余保持默认设置点击”Finish“,工程创建完成。
三、CCS设置生成hex文件
1.右击工程---->>Proprtties
2.选择C2000 Hex Utility------>>勾选 Enable ‘C2000 Hex Utility’
3.选择Output Format Options—>>选择Intel hex。(根据自己需求选择)
4.选择General Options---->>在Specify rom width处输入16. (因为该芯片一个地址占2个字节,即16位)。然后点击"Apply and Close"。
5.Swap。
注:UniFlash烧录hex默认是不选Swap数据,即UniFlash烧录时会自动对数据一个 字(WORD)进行高低字节转换
例如下方是生成没有勾选Swap的hex,hex文件中数据是0x8000=0x7640,实际烧录是0x8000=0x4076
四、添加Flash API静态库与头文件
1.右击工程---->>Proprtties
2.选择C2000 Compiler—>>>Include Options 按图上箭头添加头文件 文件夹 D:\ti\c2000\C2000Ware_3_03_00_00\libraries\flash_api\f28004x\include
根据自己C2000Ware实际安装路径选择
3.添加完后显示如下
4.根据相同方法添加如下文件夹
5.同样在C2000 Linker–>>File Search Path下添加如下
6.设置结束 点击"Apply and Close"
7.添加链接文件:右击工程---->>Add Files
8.添加如下3个文件,点击"打开"。文件路径D:\ti\c2000\C2000Ware_3_03_00_00\device_support\f28004x\common\source
根据C2000Ware实际安装目录选择
9.步骤8会弹出如下界面,选择Link to files—>>OK
根据自己需要选择Copy与Link
10.添加如下文件,路径D:\ti\c2000\C2000Ware_3_03_00_00\device_support\f28004x\headers\source
根据C2000Ware实际安装目录选择
11.添加如下文件,D:\ti\c2000\C2000Ware_3_03_00_00\device_support\f28004x\headers\cmd
根据C2000Ware实际安装目录选择
12.至此工程配置完成
五、Flash API
具体使用可以参考 TMS320F28004x Flash API Version 1.56.01.00 Reference Guide文档
文档路径D:\ti\c2000\C2000Ware_3_03_00_00\libraries\flash_api\f28004x\docs
根据C2000Ware实际安装路径选择
1.Flash初始化
uint32 FlashAPI_Init(void)
{
Fapi_StatusType oReturnCheck;
oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 100);
if(oReturnCheck != Fapi_Status_Success)
{
// Check Flash API documentation for possible errors
return oReturnCheck;
}
oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank0);
if(oReturnCheck != Fapi_Status_Success)
{
// Check Flash API documentation for possible errors
return oReturnCheck;
}
return Fapi_Status_Success;
}
2.擦除
typedef struct {
uint32 *StartAddr;
} SECTOR;
SECTOR Sector[32]= {
//bank0
(uint32 *) 0x00080000,(uint32 *) 0x00081000,
(uint32 *) 0x00082000,(uint32 *) 0x00083000,
(uint32 *) 0x00084000,(uint32 *) 0x00085000,
(uint32 *) 0x00086000,(uint32 *) 0x00087000,
(uint32 *) 0x00088000,(uint32 *) 0x00089000,
(uint32 *) 0x0008A000,(uint32 *) 0x0008B000,
(uint32 *) 0x0008C000,(uint32 *) 0x0008D000,
(uint32 *) 0x0008E000,(uint32 *) 0x0008F000,
//bank1
(uint32 *) 0x00090000,(uint32 *) 0x00091000,
(uint32 *) 0x00092000,(uint32 *) 0x00093000,
(uint32 *) 0x00094000,(uint32 *) 0x00095000,
(uint32 *) 0x00096000,(uint32 *) 0x00097000,
(uint32 *) 0x00098000,(uint32 *) 0x00099000,
(uint32 *) 0x0009A000,(uint32 *) 0x0009B000,
(uint32 *) 0x0009C000,(uint32 *) 0x0009D000,
(uint32 *) 0x0009E000,(uint32 *) 0x0009F000,
};
uint32 Flash_Erase(uint32 SectorMask)
{
int i=0;
Fapi_FlashStatusType oFlashStatus;
Fapi_StatusType oReturnCheck;
for(i=0;i<32;i++)//芯片有32个扇区
{
if((SectorMask>>i)&1)
{
oReturnCheck = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector,Sector[i].StartAddr);
// Wait until FSM is done with erase sector operation
while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
if(oReturnCheck != Fapi_Status_Success){
return 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){
return oReturnCheck;
}
}
}
return Fapi_Status_Success;
}
3.编程
边界对齐:Flash :64bit,OTP:128bit
uint32 Flash_ProgramPage(uint32 *pu32StartAddress,uint16 *pu16DataBuffer,uint16 uPageWordNum)
{
Fapi_FlashStatusType oFlashStatus;
Fapi_StatusType oReturnCheck;
//Fapi_FlashStatusWordType oFlashStatusWord;
oReturnCheck = Fapi_issueProgrammingCommand(pu32StartAddress, pu16DataBuffer, uPageWordNum,
0, 0, Fapi_AutoEccGeneration);
// Wait until the Flash program operation is over
while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy)
if(oReturnCheck != Fapi_Status_Success)
{
return 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)
{
return oFlashStatus;
}
}
4.校验
uint32 Flash_Verify(uint32 *pu32StartAddress,uint16 *pu16DataBuffer,uint16 uPageWordNum)
{
// 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 = Fapi_doVerify(pu32StartAddress,
uPageWordNum/2,(uint32*)pu16DataBuffer,
&oFlashStatusWord);
}
六、修改CMD文件内容
使用默认280049_RAM_lnk.cmd,编译出的hex文件数据都在芯片RAM区。但是数据分散在不同的RAM区,是不连续的。为了方便数据使用通过修改CMD文件使数据编译生成到一起。
1.地址修改如下:
将BEGIN生成代码从0x000000改成0x008000,即生成代码从 RAMM0 转到 RAMLS0。
由于BEGIN占用2个地址,所以RAMLS0地址要向后偏移2即从0x008000改成0x008002,大小也要减2,即0x000800改成0x0007fe
BEGIN : origin = 0x000000, length = 0x000002
BEGIN : origin = 0x008000, length = 0x000002
RAMLS0 : origin = 0x008000, length = 0x000800
RAMLS0 : origin = 0x008002, length = 0x0007fe
2.生成代码位置修改
将RAMM0改成RAMLS0,即以RAMLS0作为代码生成基地址
.TI.ramfunc : > RAMM0 PAGE = 0
.text : >>RAMM0 | RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4, PAGE = 0
.cinit : > RAMM0, PAGE = 0
.pinit : > RAMM0, PAGE = 0
.switch : > RAMM0, PAGE = 0
.reset : > RESET, PAGE = 0, TYPE = DSECT /* not used, */
.TI.ramfunc : > RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4 PAGE = 0
.text : >>RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4, PAGE = 0
.cinit : > RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4, PAGE = 0
.pinit : > RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4, PAGE = 0
.switch : > RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4, PAGE = 0
.reset : > RAMLS0 | RAMLS1 | RAMLS2 | RAMLS3 | RAMLS4, PAGE = 0, TYPE = DSECT /* not used, */
七、调试
1.debug前要创建ccxml配置文件:右击工程—>>New—>>Target Configuration File
2.选择芯片,点击Save。
如果创建工程时仿真器选错或漏选,可以在此处修改。
八、Flash/User-configurable DCSM OTP
- 主阵列闪存编程必须与 64 位地址边界对齐,每个 64 位字在写/擦除周期中只能编程一次。允许分别对数据和ECC 进行编程。 但是,每个 64 位数据和 16 位ECC在写/擦除周期中只能编程一次。
- DCSM OTP 编程必须与 128 位地址边界对齐,每个 128 位字只能编程一次。 例外情况是:
- DCSM OTP 中的 DCSM Zx-LINKPOINTER1 和 Zx-LINKPOINTER2 值应一起编程
- DCSM OTP 中的 DCSM Zx-LINKPOINTER3 要与 Zx-PSWDLOCK 分开。原因:除Zx-LINKPOINTER以外OPT 配置字带有ECC保护。当编程起始地址为Zx-LINKPOINTER时API会自动跳过ECC编程,默认使用Fapi_DataOnly。所以编程Zx-LINKPOINTER3不能与其他 DCSM OTP 配置字混在一起。如果其他区域与 link-pointers混在一起, API 会跳过 ECC 编程. 会导致应用程序 ECC 错误
DCSM Zx-LINKPOINTERx只有低29位有效,且Zx-LINKPOINTER1,2,3需要写入同一个值。
Zx-LINKPOINTER值决定了启用哪个地址区的Zone Select Block
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)