下文主要记录调用TI Flash API静态库和User OTP

一、准备工作

  1. 下载安装C2000Ware
  2. 下载安装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

  1. 主阵列闪存编程必须与 64 位地址边界对齐,每个 64 位字在写/擦除周期中只能编程一次。允许分别对数据和ECC 进行编程。 但是,每个 64 位数据和 16 位ECC在写/擦除周期中只能编程一次。
  2. 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
在这里插入图片描述
在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐