This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28075:闪存在加电后不能擦除编程

Guru**** 2847400 points

Other Parts Discussed in Thread: C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1065033/tms320f28075-flash-cannot-erase-programming-after-power-up

器件型号:TMS320F28075
主题中讨论的其他器件:C2000WARE

大家好、

以下是客户可能需要您帮助的一些问题:

F021库版本为1.54、能够擦除固件中的某些扇区并对其进行重新编程、以实现参数保存、固件升级等

当前的现象是、使用 CCS 加载.out 文件并直接运行该文件、闪存擦除编程正常。

相同的 CMD 和 OUT 文件的相同工程、一旦使用 CCS 加载、然后通过拔下仿真器重新加电、闪存状态将变为不可擦除或不可编程。

根据 fmstat 寄存器说明:Spruhm9f 文档第3.15.21.6节、检查 Fapi_getFsmStatus 在擦除后的返回值、擦除空扇区返回0x0810、除非空扇区返回0x0C10

涉及 FMSTAT 的三位:

  • bit11 在文档 A 中保留
  • 位10 eV 表示擦除错误
  • Bit4 Cstat 指示执行命令时出错

闪存寄存器有两种情况:

```
#The FLASH control register is not erased when the FLASH is not erased by power-up again 
0x05F800 0200 0000 0000 0000 0000 0000 0000 0000
0x05F808 0000 0000 0000 0000 0000 0000 0000 0000
0x05F810 0000 0000 0000 0000 0000 0000 0000 0000
0x05F818 0000 0000 0000 0000 0000 0000 000F 0000
0x05F820 0003 0000 8001 0000 0001 0860 0000 0000
0x05F828 0000 0000 0000 0000 0000 0000 0000 0000
0x05F830 00FC 0000 55AA 0000 0000 0000 0000 0000
0x05F838 0000 0000 0000 0000 0000 0000 0000 0000
0x05F840 000B 0000 0055 00EB 0000 00DB 0000 000F
0x05F848 0716 0000 A000 0000 0004 0000 010A 0700
#Flash control register when CCS loads normal erase 
0x05F800 0200 0000 0000 0000 0000 0000 0000 0000
0x05F808 0000 0000 0000 0000 0000 0000 0000 0000
0x05F810 0000 0000 0000 0000 0000 0000 0000 0000
0x05F818 0000 0000 0000 0000 0000 0000 000F 0000
0x05F820 0003 0000 8001 0000 0001 0860 0000 0000
0x05F828 0000 0000 0000 0000 0000 0000 0000 0000
0x05F830 00FC 0000 0000 0000 0000 0000 0000 0000
0x05F838 0000 0000 0000 0000 0000 0000 0000 0000
0x05F840 000B 0000 008C 01E9 0000 01BE 0000 0000
0x05F848 071B 0000 9000 0000 0004 0000 010A 0700
```

本文档中列出的寄存器没有明显的错误、但是有一些不同的地址在本文档中没有描述。 客户想知道如何进一步诊断此问题?

FlashAPI 和其他与闪存相关的代码位于 SRAM 中、只有闪存在加电后无法正确擦除编程、并且其他固件功能正常、包括闪存读取。 在使用 F28075之前、在 F280049上使用了相同的代码、没有任何问题。 这次只是取代了 FlashAPI、它非常相似、但不完全相同。

您可以帮助检查此案例吗? 谢谢。

此致、

樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我是客户、请给我一些提示、谢谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Xiao、

    很抱歉耽误你的答复。  这是今天分配给我的。   

    您能否在闪存 API 函数调用之前检查 EALLOW 是否已启用?  F2807x API V1.54需要应用程序根据需要调用 EALLOW/EDIS。  F280049无需调用 EALLOW。  

    谢谢、此致、

    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamsi、

    感谢您的支持! 由于某些限制、它们不能直接进入这里、因此我将继续在这里进行更新。

    [引用 userid="16728" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/C2000-microcontrollers-forume/1065033/tms320f28075-flash-note-erase-programming-after power-up/3944972#3944972"]您能否在调用闪存函数之前检查是否启用了 EALLOW?]

    是的、它们确实启用 EALLOW。

    如前所述、它们使用 CCS 加载.out 文件并直接运行、闪存擦除编程都可以正常工作。 如果没有 EALLOW/EDIS、CCS 不应直接加载、对吗?

    谢谢、此致、

    樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    樱桃

    CCS 闪存加载是由于 CCS 闪存插件(由我们开发)所致。

    我询问用户应用程序使用闪存 API 的情况。  请检查并告知我。

    谢谢、此致、
    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamsi、

    感谢您的澄清、我将与客户核实、并希望收到修改后的更新。

    谢谢、此致、

    樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamsi、

    以下是一些说明:

    擦除闪存是指在 CCS 加载程序后运行程序、然后 SCIA 连接到芯片、并输入一条命令将其擦除。 此擦除命令在 CCS 已加载时执行。 但是、SCS 已完成加载相同的.out 固件、并且在重新加电后无法执行擦除命令。 应用程序将 EALLOW 和 EDIS 添加到闪存 API 访问中。

    以下函数用于初始化 FlashAPI 和擦除扇区、并添加了 EALLOW 和 EDIS:

    #pragma CODE_SECTION(InitFlashAPI,".TI.ramfunc");
    Fapi_StatusType InitFlashAPI(void)
    {
    	Fapi_StatusType st = Fapi_Status_Success;
    
    	EALLOW;
    
    	// using INTOSC2,PLL clock frequency 120M,120*1.03 = 123.6,take 124
    	st = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 124);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	st = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	EDIS;
    
    	return st;
    }
    
    
    #pragma CODE_SECTION(eraseFlashSector,".TI.ramfunc");
    Uint32 eraseFlashSector(Uint16 sector)
    {
    	Fapi_StatusType st;
    	Fapi_FlashStatusType fst;
    	Uint32 addr = 0;
    
    	if(sector < 'a' || sector > 'n')
    	{
    		return 0;
    	}
    
    	addr = flashSectorStart[sector - 'a'];
    
    	EALLOW;
    	st = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32*)addr);
    	while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
    	{
    		KickDog();
    	}
    	// FLASH0CTRL_BASE = 0x05F800 FMSTAT Offset 0x2A 
    	//FMSTAT Register Description: Section 3.15.21.6 of the spruhm9f document 
    	// Erasing empty Sector returns 0x0810, erasing non-empty Sector returns 0x0C10 
    	fst = Fapi_getFsmStatus();
    	EDIS;
    
    	if(st != Fapi_Status_Success || fst != 0)
    	{
    		addr = 0;
    		printx("st=0x____ ", st);
    		printx("fst=0x________\r\n", fst);
    	}
    
    	return addr;
    }

    请告知这些信息是否有用。 谢谢。

    此致、

    樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    樱桃

    我将在一天内回顾并返回给您。

    谢谢、此致、

    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    樱桃

    在擦除操作之前器件是否受到保护?

    当无法从上述代码中擦除时、您提到 CCS 闪存插件能够成功擦除-对吗?

    谢谢、此致、

    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamsi、

    [引用 userid="16728" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/C2000-microcontrollers-forume/1065033/tms320f28075-flash-note-erase-programming-after power-up/3947150#3947150"]器件在擦除操作之前是否受到保护?

    否、器件未受保护。

    [引用 userid="16728" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/C2000-microcontrollers-forume/1065033/tms320f28075-flash-note-erase-programming-after power-up/3947150#3947150"]如果无法从上述代码中擦除,则说明您已成功提及 CCS 插件/是否可以正确擦除 CCS 插件[?]

    正确。

    谢谢、此致、

    樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    樱桃

    感谢您提供信息。

    客户能否尝试使用 C2000Ware 中的闪存编程示例、看看它是否能够成功擦除闪存?  这有助于我们了解它是代码问题还是其他问题。

    谢谢、此致、

    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamsi、

    [引用 userid="16728" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/C2000-microcontrollers-forume/1065033/tms320f28075-flash-note-erase-programming-after power-up/3947735#3947735]客户能否尝试 C2000Ware 中的闪存编程示例、并成功查看闪存是否能够成功?  [/报价]

    是的、他们已经尝试过、运行良好。(C2000Ware_4_00_00_00\device_support\f2807x\examples\CPU1\flash_programming\cpu01)

    谢谢、此致、

    樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    樱桃

    在这种情况下、我认为这是他们的代码问题。   

    您能否发送一个我可以在我身边构建和运行的项目?  请删除所有专有信息。

    谢谢、此致、
    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamsi、

    再次感谢您的帮助。 但很抱歉、由于某些原因、他们无法提供项目。 我们还能找到其他方法吗?

    这里是客户的一些反馈:280049和28075芯片是第三代 C28x、闪存既是 NAND、又是 ECC、而 FlashAPI 是 F021库。 但是、一个是 管理 EALLOW/EDIS 的库、而另一个是让客户管理 EALLOW/EDIS。 对于客户来说、这可能不是很方便。  

    谢谢、此致、

    樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    樱桃

    我们过去曾与其他使用相同闪存包装程序的非 C2000团队共享我们的代码。  这些团队要求我们不要在闪存 API 中包含特定于内核的内容。  因此、我们之前没有包含 EALLOW/EDIS。  稍后、我们决定在 F28004x 时间范围内包含 EALLOW/EDIS、以减少用户的额外工作量。

    关于项目共享:好的、如果他们无法共享、他们是否可以将其应用程序与 C2000Ware 中的闪存 API 编程示例进行比较?

    此外、搜索"当闪存 API 无法擦除或编程时、我们可以考虑哪些常见调试提示?" 在本常见问题解答中: https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/951668 

    谢谢、此致、
    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamsi、

    谢谢!  

    相同的.out 目标文件、在 CCS 加载时直接运行、正常擦除闪存、但无法在加电后再次擦除。 如果使用 C2Prog 等第三方工具刻录.out 文件、并在刻录完成后直接运行该文件而不断电、 则也无法擦除闪存。 因此、很明显、CCS 在加载目标文件时执行了一些额外的工作。 客户想知道擦除闪存的额外工作。

    F28075.GEL 中的 OnReset()函数 有一个 SetupDCSM()来配置可能与加密相关的加密模块 DCSM,并且 CCS 加载在删除后仍然可以被正确擦除,这意味着 DCSM 不是很相关。

    在客户的工程未使用 DCSM 进行加密的情况下、是否需要执行其他工作来确保闪存可擦除?

    如果 DCSM 不用于加密,是否需要在初始化期间调用 dcsm_unlockZone1csm()以使用完整的 FF 密码进行解密?

    [引用 userid="16728" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/C2000-microcontrollers-forume/1065033/tms320f28075-flash-note-erase-programming-after power-up/3950204#3950204"]关于项目共享

    下面是 HAL.c 文件、其中包括函数的初始化:

    #include <hal.h>
    
    //*****************************************************************************
    //
    // Function to initialize the device. Primarily initializes system control to a
    // known state by disabling the watchdog, setting up the SYSCLKOUT frequency,
    // and enabling the clocks to the peripherals.
    //
    //*****************************************************************************
    void Device_init(void)
    {
    	SysCtl_disableWatchdog();
    
    #ifdef _FLASH
    	//
    	// Copy time critical code and flash setup code to RAM. This includes the
    	// following functions: InitFlash();
    	//
    	// The RamfuncsLoadStart, RamfuncsLoadSize, and RamfuncsRunStart symbols
    	// are created by the linker. Refer to the device .cmd file.
    	//
    	//memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t) &RamfuncsLoadSize);
    #endif
    
    	//
    	// Set up PLL control and clock dividers
    	//
    	SysCtl_setClock(DEVICE_SETCLOCK_CFG);
    
    	//
    	// Make sure the LSPCLK divider is set to the default (divide by 4)
    	//
    	SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);
    
    	//
    	// These asserts will check that the #defines for the clock rates in
    	// device.h match the actual rates that have been configured. If they do
    	// not match, check that the calculations of DEVICE_SYSCLK_FREQ and
    	// DEVICE_LSPCLK_FREQ are accurate. Some examples will not perform as
    	// expected if these are not correct.
    	//
    	ASSERT(SysCtl_getClock(DEVICE_OSCSRC_FREQ) == DEVICE_SYSCLK_FREQ);
    	ASSERT(SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ) == DEVICE_LSPCLK_FREQ);
    
    	//
    	// Call Flash Initialization to setup flash waitstates. This function must
    	// reside in RAM.
    	//
    	Flash_initModule(FLASH0CTRL_BASE, FLASH0ECC_BASE, DEVICE_FLASH_WAITSTATES);
    
    	//
    	// Turn on all peripherals
    	//
    	Device_enableAllPeripherals();
    }
    
    //*****************************************************************************
    //
    // Function to turn on all peripherals, enabling reads and writes to the
    // peripherals' registers.
    //
    // Note that to reduce power, unused peripherals should be disabled.
    //
    //*****************************************************************************
    void Device_enableAllPeripherals(void)
    {
    #if 1
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIC);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCID);
    #else
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CLA1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DMA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER0);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TIMER2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_HRPWM);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EMIF1);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM6);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM7);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM8);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM9);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM10);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM11);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EPWM12);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ECAP6);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_EQEP3);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SD2);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCIC);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SCID);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_SPIC);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_I2CB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCBSPA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_MCBSPB);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_USBA);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCB);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_ADCD);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS1);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS2);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS3);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS4);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS5);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS6);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS7);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CMPSS8);
    
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACA);
    	SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_DACB);
    #endif
    }
    
    //*****************************************************************************
    //
    // Function to disable pin locks and enable pullups on GPIOs.
    //
    //*****************************************************************************
    void Device_initGPIO(void)
    {
    
    }
    
    #pragma CODE_SECTION(InitFlashAPI,".TI.ramfunc");
    Fapi_StatusType InitFlashAPI(void)
    {
    	Fapi_StatusType st = Fapi_Status_Success;
    
    	EALLOW;
    
    	// 使用INTOSC2,PLL主频120M,120*1.03 = 123.6,取124
    	st = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, 124);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	st = Fapi_setActiveFlashBank(Fapi_FlashBank0);
    	if (st != Fapi_Status_Success)
    	{
    		return st;
    	}
    
    	EDIS;
    
    	return st;
    }
    
    // sector = a-n
    #pragma CODE_SECTION(eraseFlashSector,".TI.ramfunc");
    Uint32 eraseFlashSector(Uint16 sector)
    {
    	Fapi_StatusType st;
    	Fapi_FlashStatusType fst;
    	Uint32 addr = 0;
    
    	if(sector < 'a' || sector > 'n')
    	{
    		return 0;
    	}
    
    	addr = flashSectorStart[sector - 'a'];
    
    	EALLOW;
    	st = Fapi_issueAsyncCommandWithAddress(Fapi_EraseSector, (uint32*)addr);
    	while (Fapi_checkFsmForReady() != Fapi_Status_FsmReady)
    	{
    		KickDog();
    	}
    	// FLASH0CTRL_BASE = 0x05F800 FMSTAT偏移量0x2A
    	// FMSTAT寄存器描述:spruhm9f文档的3.15.21.6节
    	// 擦除空Sector返回0x0810,擦除非空Sector返回0x0C10
    	fst = Fapi_getFsmStatus();
    	EDIS;
    
    	if(st != Fapi_Status_Success || fst != 0)
    	{
    		addr = 0;
    		printx("st=0x____ ", st);
    		printx("fst=0x________\r\n", fst);
    	}
    
    	return addr;
    }
    
    //*****************************************************************************
    //
    // Error handling function to be called when an ASSERT is violated
    //
    //*****************************************************************************
    #pragma CODE_SECTION(__error__,".TI.ramfunc");
    void __error__(char *filename, uint32_t line)
    {
    	//
    	// An ASSERT condition was evaluated as false. You can use the filename and
    	// line parameters to determine what went wrong.
    	//
    	ESTOP0;
    }
    
    // initCPUTimers - This function initializes all three CPU timers
    // to a known state.
    void initCPUTimers(void)
    {
    	//
    	// Initialize timer period to maximum
    	//
    	CPUTimer_setPeriod(CPUTIMER0_BASE, 0xFFFFFFFF);
    	CPUTimer_setPeriod(CPUTIMER1_BASE, 0xFFFFFFFF);
    	CPUTimer_setPeriod(CPUTIMER2_BASE, 0xFFFFFFFF);
    
    	//
    	// Initialize pre-scale counter to divide by 1 (SYSCLKOUT)
    	//
    	CPUTimer_setPreScaler(CPUTIMER0_BASE, 0);
    	CPUTimer_setPreScaler(CPUTIMER1_BASE, 0);
    	CPUTimer_setPreScaler(CPUTIMER2_BASE, 0);
    
    	//
    	// Make sure timer is stopped
    	//
    	CPUTimer_stopTimer(CPUTIMER0_BASE);
    	CPUTimer_stopTimer(CPUTIMER1_BASE);
    	CPUTimer_stopTimer(CPUTIMER2_BASE);
    
    	//
    	// Reload all counter register with period value
    	//
    	CPUTimer_reloadTimerCounter(CPUTIMER0_BASE);
    	CPUTimer_reloadTimerCounter(CPUTIMER1_BASE);
    	CPUTimer_reloadTimerCounter(CPUTIMER2_BASE);
    }
    
    // configCPUTimer - This function initializes the selected timer to the
    // period specified by the "freq" and "period" parameters. The "freq" is
    // entered as Hz and the period in uSeconds. The timer is held in the stopped
    // state after configuration.
    void configCPUTimer(uint32_t cpuTimer, float freq, float period)
    {
    	uint32_t temp;
    
    	//
    	// Initialize timer period:
    	//
    	temp = (uint32_t) (freq / 1000000 * period);
    	CPUTimer_setPeriod(cpuTimer, temp);
    
    	//
    	// Set pre-scale counter to divide by 1 (SYSCLKOUT):
    	//
    	CPUTimer_setPreScaler(cpuTimer, 0);
    
    	//
    	// Initializes timer control register. The timer is stopped, reloaded,
    	// free run disabled, and interrupt enabled.
    	// Additionally, the free and soft bits are set
    	//
    	CPUTimer_stopTimer(cpuTimer);
    	CPUTimer_reloadTimerCounter(cpuTimer);
    	CPUTimer_setEmulationMode(cpuTimer,
    			CPUTIMER_EMULATIONMODE_STOPAFTERNEXTDECREMENT);
    	CPUTimer_enableInterrupt(cpuTimer);
    }
    
    
    #pragma CODE_SECTION(DELAY_MS,".TI.ramfunc");
    void DELAY_MS(Uint16 n)
    {
    	while(n--)
    	{
    		KickDog();
    		DEVICE_DELAY_US(500);
    		KickDog();
    		DEVICE_DELAY_US(500);
    	}
    }
    
    #pragma CODE_SECTION(SystemReset,".TI.ramfunc");
    void SystemReset(void)
    {
    	SysCtl_resetDevice();
    }
    
    const Uint32 flashSectorStart[14] =
    {
    	0x080000, 0x082000, 0x084000, 0x086000,
    	0x088000, 0x090000, 0x098000, 0x0A0000, 0x0A8000, 0x0B0000,
    	0x0B8000, 0x0BA000, 0x0BC000, 0x0BE000
    };
    const Uint32 flashSectorSize[14] =
    {
    	0x2000, 0x2000, 0x2000, 0x2000,
    	0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000,
    	0x2000, 0x2000, 0x2000, 0x2000,
    };
    
    #pragma CODE_SECTION(isFlashEmpty,".TI.ramfunc");
    Uint32 isFlashEmpty(Uint32 start, Uint32 len)
    {
    	Fapi_FlashStatusWordType fswt;
    	Fapi_StatusType st;
    
    	EALLOW;
    	st = Fapi_doBlankCheck((Uint32 *)start, len>>1, &fswt);
    	EDIS;
    
    	if(Fapi_Status_Success == st)
    	{
    		return 0;
    	}
    	else
    	{
    		return fswt.au32StatusWord[0];
    	}
    }
    
    //
    // Fapi_serviceWatchdogTimer - Watchdog servicing function
    //
    #pragma CODE_SECTION(Fapi_serviceWatchdogTimer,".TI.ramfunc");
    Fapi_StatusType Fapi_serviceWatchdogTimer(void)
    {
       //
       // User to add their own watchdog servicing code here
       //
       KickDog();
       return(Fapi_Status_Success);
    }
    
    //
    // Fapi_setupEepromSectorEnable - Enables EEPROM sectors for bank and sector
    //                                erase
    //
    #pragma CODE_SECTION(Fapi_setupEepromSectorEnable,".TI.ramfunc");
    Fapi_StatusType Fapi_setupEepromSectorEnable(void)
    {
       //
       // Value must be 0xFFFF to enable erase and programming of the
       // EEPROM bank, 0 to disable
       //
       Fapi_GlobalInit.m_poFlashControlRegisters->Fbse.u32Register = 0xFFFF;
    
       //
       // Enables sectors 32-63 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector.u32Register,
                                      0x0U);
    
       //
       // Enables sectors 0-31 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector1.u32Register,
                                      0x0U);
    
       //
       // Enables sectors 32-63 for bank and sector erase
       //
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector2.u32Register,
                                      0x0U);
    
       return(Fapi_Status_Success);
    }
    
    //
    // Fapi_setupBankSectorEnable - Setup and enable bank sectors 0-15
    //
    #pragma CODE_SECTION(Fapi_setupBankSectorEnable,".TI.ramfunc");
    Fapi_StatusType Fapi_setupBankSectorEnable(void)
    {
       //
       // Enable sectors 0-15 for erase and programming
       //
       Fapi_GlobalInit.m_poFlashControlRegisters->Fbse.u32Register = 0xFFFF;
       FAPI_WRITE_LOCKED_FSM_REGISTER(Fapi_GlobalInit.m_poFlashControlRegisters->FsmSector.u32Register,
                                      0x0U);
    
       return(Fapi_Status_Success);
    }

    main.c 操作逻辑:

    #include <hal.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <stdio.h>
    #include "main.h"
    #include "syscall.h"
    #include "util.h"
    
    
    void main(void)
    {
    //	CopyLibrary();
    	Device_init();
    	Device_initGPIO();
    	InitFlashAPI();
    	EEPROM_Init();
    	EEPROM_Load();
    	initCPUTimers();
    	configCPUTimer(CPUTIMER0_BASE, DEVICE_SYSCLK_FREQ, 10000);	// 10ms sysTick
    	Interrupt_initModule();
    	Interrupt_initVectorTable();
    	InitSystem();
    	Run();
    }
    
    void InitSystem(void)
    {
    	BOOL isSave = FALSE;
    
    	Interrupt_register(INT_TIMER0,  &cpuTimer0ISR);
    	Interrupt_enable(INT_TIMER0);
    
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT1);
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT8);
    	Interrupt_enableInCPU(INTERRUPT_CPU_INT9);
    
    	EINT;
    	ERTM;
    
    	if(isSave)
    	{
    		EEPROM_Save();
    	}
    }
    
    #pragma CODE_SECTION(CleanUp,".TI.ramfunc");
    void CleanUp(void)
    {
    //	DeInitECana();
    	CPUTimer_stopTimer(CPUTIMER0_BASE);
    	__disable_interrupts();
    	SysCtl_disableWatchdog();
    }
    
    #pragma CODE_SECTION(Run,".TI.ramfunc");
    void Run(void)
    {
    	BOOL isRunUserApp = TRUE;
    
    	LED_ON();
    	CPUTimer_startTimer(CPUTIMER0_BASE);
    
    	SysCtl_setWatchdogPrescaler(SYSCTL_WD_PRESCALE_64);
    	SysCtl_enableWatchdog();
    
    	while(TRUE)
    	{
    		tskSyscall(&scia);
    		tskSyscall(&scib);
    		tskSyscall(&scic);
    		KickDog();
    	}
    }
    
    #pragma CODE_SECTION(cpuTimer0ISR,".TI.ramfunc");
    __interrupt void cpuTimer0ISR(void)
    {
    	ymodem.timeout++;
    	sysTickTimer++;
    	if(sysTickTimer > 50)
    	{
    		LED_SET(sysTickTimer&0x40);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
    }
    
    // SCIA
    #pragma CODE_SECTION(sciaRxISR,".TI.ramfunc");
    __interrupt void sciaRxISR(void)
    {
    	CONSOLE_REGS *sci = &scia;
    	if(UART_SCIA == (consoleMask & UART_SCIA))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIA;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    // SCIB
    #pragma CODE_SECTION(scibRxISR,".TI.ramfunc");
    __interrupt void scibRxISR(void)
    {
    	CONSOLE_REGS *sci = &scib;
    
    	if(UART_SCIB == (consoleMask & UART_SCIB))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIB;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP9);
    }
    
    // SCIC
    #pragma CODE_SECTION(scicRxISR,".TI.ramfunc");
    __interrupt void scicRxISR(void)
    {
    	CONSOLE_REGS *sci = &scic;
    
    	if(UART_SCIC == (consoleMask & UART_SCIC))
    	{
    		if((HWREGH(sci->iface.sci + SCI_O_RXST) & SCI_RXST_RXRDY) == SCI_RXST_RXRDY)
    		{
    			consoleUsed = UART_SCIC;
    		}
    		tskRecvSciData(sci);
    	}
    	Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP8);
    }

    关于闪存操作寄存器、是否有任何进一步的说明? 擦除报告错误、实际返回的位4和位10并不告诉用户错误是什么。  

    谢谢、此致、

    樱桃

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    樱桃

    1) 1)使用了什么闪存等待状态值?

    2) 2)对于 fapi_initiatizeAPI (),他们能否尝试120MHz,而不是124Mhz。  我知道他们为什么要使用这个比这个值高3%的值-但这不是必需的。  我们正在更新指南以删除该要求。  我认为这与当前调试没有任何关系、但只想通知。

    3) 3)闪存插件不执行任何额外操作-它遵循与闪存 API 示例中概述的步骤相同。

    4) fmstat 值只是表示擦除验证不成功-这意味着擦除不成功。  保留位不提供任何额外信息-因此未记录。

    5) 5)关于 DCSM 问题: 请参阅以下 TRM 的片段。  请看一下案例2以及下面的注释。

    6) 6)当您说闪存擦除在上电后不成功时、它们是独立运行(在闪存引导模式下)还是在连接 JTAG 的情况下运行?

    谢谢、此致、
    Vamsi

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Vamsi、

    非常感谢您的支持和努力!

    此问题已通过从 FlashAPI 中的看门狗回调函数 Fapi_serviceWatchdog Timer()中删除 KICK 操作得到解决。 功能如下:

    //
    // Fapi_serviceWatchdogTimer - Watchdog servicing function
    //
    #pragma CODE_SECTION(Fapi_serviceWatchdogTimer,".TI.ramfunc");
    Fapi_StatusType Fapi_serviceWatchdogTimer(void)
    {
       //
       // User to add their own watchdog servicing code here
       //
    
       return(Fapi_Status_Success);
    }

    在注释中:它要求客户添加自己的 kick dog 操作,然后加上 SysCtl_serviceWatchdog(),最终导致此问题。 也许我们可以找出一些方法来避免这个错误。  

    再次感谢!

    此致、

    樱桃