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.

[参考译文] TMS320F2.8069万:TMS320F2.8069万进入低功耗模式

Guru**** 2540720 points
Other Parts Discussed in Thread: CONTROLSUITE

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/617479/tms320f28069-tms320f28069-going-into-low-power-mode

部件号:TMS320F2.8069万
主题: controlSUITE中讨论的其他部件

正如标题所示,我使用的是TMS320F2.8069万 MCU。

我的代码大致描述如下:当设备通电时,它将直接进入GetMode。 从那里,它会闪存。 在闪存开始时,辅助引导加载程序(我编写的) 确定是将代码加载到其他闪存扇区(此辅助引导加载程序保存在从未擦除的扇区中),还是继续使用已在闪存中的代码。 如果需要加载新代码,它将进入SCI引导模式。 从那里,  C2000串行固件升级器的修改版本用于将f2.8069万_flash_kernel加载到RAM。 f2.8069万_flash_kernel将新代码加载到闪存中。 C2000串行固件升级器和f2.8069万_flash_kernel都是从controlSUITE获得的。

在测试辅助引导加载程序时,我想 在f2.8069万_flash_kernel尝试加载到闪存时物理断开计算机和MCU之间的串行电缆。 这样做是因为我的辅助引导加载程序在引导时必须始终可用,以便将代码加载到闪存。 因此,应该没有办法阻止将代码加载到闪存中。 我的辅助引导加载程序仅位于扇区A,其余代码位于其他闪存扇区。

我能够反复执行此测试,没有问题。 但是,  在最近的一次测试中,MCU进入了低功耗模式。 我尝试使用Code Composer和JTAG 端口下载代码。 但是,当我 尝试这样做时,它说它处于低功耗模式,不允许我重新下载代码。

我尝试重启主板,但它仍然进入低功耗模式。 这表示闪存中一定有某个东西会将其设置为低功耗模式。

基于所有这些,我有以下问题:

1.当处于低功耗模式时,我是否应该只强制GPIO引脚处于特定状态,关闭电源再打开,然后尝试使用JTAG重新加载? 或者只需将XRS引脚拉高就足够了吗?

2.我的辅助引导加载程序代码中没有处理低功耗模式寄存器的内容。 请参阅下面我的main.c。  同样,这完全是在A区(在发生此问题之前,我检查了拆卸过程,以验证是否发生了此问题)。 但是,正如我所提到的,如果它在一个电源循环后仍进入低功耗模式,则闪存中一定会有某种东西将它设置为低功耗模式之一。 这怎么可能? 如有任何建议,我们将不胜感激。

/****************************************************************

*文件:main.c.

*器件:TMS320F2806x

*************** /

#define main_C

#include "main.h"//主include文件

#include <F2806X_Device.h>// F2806x头文件外围设备地址定义

#include "DynaLinkBegin.h"

#include <Flash2806X_API_Library.h>

#pragma code_section (bootloaderStart,"bootStart")

#pragma code_section (CsmUnlock_Bootloader,"bootStart")

#pragma code_section (SCI_Init_Bootloader,"bootStart")

#pragma code_section (SCI_Autobaud_Bootloader,"bootStart")

#pragma code_section (main,"bootStart")

#pragma code_section (sci_msg_boot,"bootStart")

#pragma code_section (sci_xmit_boot,"bootStart")

void bootloaderStart(void);

UINT16 CsmUnlock_Bootloader(void);

void SCI_Init_Bootloader(void);

UINT16 SCI_Autobaud_Bootloader(void);

void sci_msg_boot(UINT16 p, unsigned char *msg);

void sci_xmit_boot(UINT16 p, unsigned char a);

extern void SciBoot(void);

//在Passwords.asm中定义

// CSM键值

UINT16 PRG_KEY0;

UINT16 PRG_KEY1;

UINT16 PRG_KEY2;

UINT16 PRG_KEY3;

UINT16 PRG_KEY4;

UINT16 PRG_KEY5;

UINT16 PRG_KEY6;

UINT16 PRG_KEY7;

Void主(void)

bootloaderStart();

DynalinkMain();

}//main()的结尾

/*------------------

CsmUnlock_Bootloader

解锁代码安全模块(CSM)

参数:

返回值:

STATUS_SUCCESS CSM已解锁

STATUS_FAIL_UNLOCK CSM未解锁

注:

---------------------------------- */

UINT16 CsmUnlock_Bootloader()

易失性UINT16温度;

//使用当前密码加载密钥寄存器

//这些在example_Flash2806x_CsmKeys.asm中定义

ASM (" EALLOW");

CsmRegs.KEY0 = PRG_KEY0;

CsmRegs.key1 = PRG_key1;

CsmRegs.key2 = PRG_key2;

CsmRegs.key3 = PRG_key3;

CsmRegs.KEY4 = PRG_KEY4;

CsmRegs.KEY5 = PRG_KEY5;

CsmRegs.KEY6 = PRG_KEY6;

CsmRegs.KEY7 = PRG_KEY7;

ASM (" EDIS");

//执行密码位置的虚拟读取

//如果它们与密钥值匹配,CSM将解锁

TEMP = CsmPwl.PSWD0

TEMP = CsmPwl.PSWD1

TEMP = CsmPwl.PSWD2

TEMP = CsmPwl.PSWD3

TEMP = CsmPwl.PSWD4

TEMP = CsmPwl.PSWD5

TEMP = CsmPwl.PSWD6

TEMP = CsmPwl.PSWD7

//如果CSM已解锁,则返回成功,否则返回

//失败。

如果((CsmRegs.CSMSCR.ALL & 0x0001)== 0)

返回STATUS_SUCCESS;

否则

返回STATUS_FAIL_CSM_LOCKED;

}

/*------------------

SCI_Init_Bootloader

SCI初始化。

参数:

返回值:

注:

自定义SCI初始化其内嵌以确保

可以进行自动波特率和脱字符传输。 在中也需要它

以便在ROM中成功分支到SCI引导模式。

---------------------------------- */

void SCI_Init_Bootloader()

ASM (" EALLOW");

//启用SCI-A时钟。

SysCtrlRegs.PCLKCR0.bit.SCIANCLK=1;

SysCtrlRegs.LOSPPCN.ALL = 0x0002;

//重置SCI FIFO传输寄存器。

SciaRegs.SCIFFTX.ALL = 0x8000;

// 1个停止位,无奇偶校验,8位字符

SciaRegs.SCICCR.ALL = 0x0007;

//启用TX和RX。

SciaRegs.SCICTL1.all = 0x0003;

//禁用TX和RX中断和标志。

SciaRegs.SCICT2.all = 0x0000;

//SCI复位,同时保持TX和RX启用。

SciaRegs.SCICTL1.all = 0x0023;

//启用SCI-A引脚上的上拉

// GpioCtrlRegs.GPAPUD.bit.GPIO28 = 0;

// GpioCtrlRegs.GPAPUD.bit.GPIO29 = 0;

gpioCtrlRegs.gpapud.all &= 0xCFFFFFFF;

//启用SCI-A引脚

// GpioCtrlRegs.GPAMUX2.bit.GPIO28 = 1;

// GpioCtrlRegs.GPAMUX2.bit.GPIO29 = 1;

gpioCtrlRegs.GPAMUX2.all |= 0x500万;

// SCI-A RX的输入qual为异步

GpioCtrlRegs.GPAQSEL2.bit.GPIO28 = 3;

SciaRegs.SCIHBAUD = 0x0000;

SciaRegs.SCILBAUD = 0x0000;

SciaRegs.SCIFFRX.ALL = 0x201F;

SciaRegs.SCIFFCT.ALL = 0x0000;

SysCtrlRegs.WDCR = 0x0068;//禁用监视程序。

SysCtrlRegs.CLKCTL.bit.INTOSC1OFF = 0;//打开内部振荡器1

SysCtrlRegs.CLKCTL.bit.OSCCLKSRCSEL = 0;// Clk src = INTOSC1

SysCtrlRegs.CLKCTL.bit.XCLKINOFF = 1;//关闭XCLKIN

SysCtrlRegs.CLKCTL.bit.XTALLOSCOFF = 1;//关闭XTALOSC

SysCtrlRegs.CLKCTL.bit.INTOSC2OFF = 1;//关闭INTOSC2

//确保PLL未在跛行模式下运行。

如果(SysCtrlRegs.PLLSTS.bit.MCLKSTS !=0){

EALLOW;

//检测到OSCCLKSRC1故障。 PLL在跛行模式下运行。

//重新启用缺少的时钟逻辑。

SysCtrlRegs.PLLSTS.bit.MCLKCLR = 1;

EDIS;

//将此线路替换为呼叫适当的

// SystemShutdown();函数。

_ASM (" ESTOP0");

//调试目的取消注释

}

// DIVSEL必须为0,然后才能更改PLLCR

// 0x0000。 通过外部重置XRSn将其设置为0

//这让我们进入1/4

SysCtrlRegs.PLLSTS.bit.DIVSEL = 0;

//更改PLLCR

如果(SysCtrlRegs.PLLCR.bit.DIV !=18){

//在设置PLLCR之前,请关闭缺少时钟检测逻辑

SysCtrlRegs.PLLSTS.bit.MCLKOFF = 1;

SysCtrlRegs.PLLCR.bit.DIV = 18;

//可选:等待PLL锁定。

//在此期间,CPU将切换到OSCCLK/2,直到

// PLL稳定。 PLL稳定后,CPU将保持稳定

//切换到新的PLL值。

//

//此锁定时间由PLL锁定计数器监控。

//

//等待PLL锁定时不需要密码。

//但是,如果代码执行任何对时间至关重要的操作,

//并要求锁定正确的时钟,则最好是

//等待此切换完成。

//等待PLL锁定位设置。

同时(SysCtrlRegs.PLLSTS.bit.PLLLOCKS !=1){

//取消注释以服务监视程序

// ServiceDog ();

}

SysCtrlRegs.PLLSTS.bit.MCLKOFF = 0;

}

SysCtrlRegs.PLLSTS.bit.DIVSEL = 2;

ASM (" EDIS");

}

/*------------------

SCI_Autobaud_Bootloader

参数:

返回值:

注:

这将确定SCI传输的波特率

发生。 这是必需的,因为需要先传送脱字符

进入ROM中的SCI引导模式。

---------------------------------- */

UINT16 SCI_Autobaud_Bootloader()

UINT16字节数据;

UINT16超时;

UINT32 j;

UINT32 timePeriodBL = 6000万;

//必须使用>=1进行初始波特寄存器

SciaRegs.SCILBAUD = 1;

//准备自动波特率检测

//设置CDC位以启用自动波特检测

//并清除Abd位

SciaRegs.SCIFFCT.bit.CDC = 1;

SciaRegs.SCIFFCT.Bit.ABDCLR = 1;

//等待我们正确读取

//'A'或'A'并锁定

超时= 0;

while ((SiaRegs.SCIFFCT.bit.Abd !=1)&&(timeout == 0))

用于(j=0;(j<timePeriodBL)&&(SiaRegs.SCIFFCT.bit.Abd !=1);j++){};

如果(j >= timePeriodBL){timeout = 1;}

}

//自动波特锁后,清除Abd和CDC位

SciaRegs.SCIFFCT.Bit.ABDCLR = 1;

SciaRegs.SCIFFCT.bit.CDC = 0;

IF (超时== 0)

while ((SiaRegs.SCIRXST.bit.RXRDY !=1)&&(timeout ==0))

用于(j=0;(j<timePeriodBL)&&(SiaRegs.SCIRXST.bit.RXRDY !=1);j++){};

如果(j >= timePeriodBL){timeout = 1;}

}

IF (超时== 0)

byteData = SciaRegs.SCIRXBUF.bit.RXDT;

SciaRegs.SCITXBUF =字节数据;

}

}

返回超时;

}

void bootloaderStart()

UINT16状态;

UINT16字节数据;

UINT16 autoBaudStatus =1;

UINT16超时;

UINT32 j;

UINT32 timePeriodBLS = 6000万;

状态= CsmUnlock_Bootloader();

如果(状态== status_success){

// SCI_Boot之前的初始化

SCI_Init_Bootloader();

//执行自动波特率。

AutoBaudStatus = SCI_Autobaud_Bootloader();

IF (autoBaudStatus == 0)

字节数据= 0x0000;

//等待插入记号。 如果在特定时间内收到

//of time,然后转至引导ROM中的SCI_Boot。

sci_msg_boot(0),"^"

超时= 0;

while ((SiaRegs.SCIRXST.bit.RXRDY !=1)&&(timeout ==0))

用于(j=0;(j<timePeriodBLS)&&(SiaRegs.SCIRXST.bit.RXRDY!=1);j++)

sci_msg_boot(0),"^"

};

如果(j >= timePeriodBLS){timeout = 1;}

}

如果(超时== 0)

byteData = SciaRegs.SCIRXBUF.bit.RXDT;

//如果收到插入记号,请转至Boot ROM中的SCI_Boot。

IF (字节数据== 0x005E)

SciBoot();

ASM (" EDIS");

}

}

}

}

}

void sci_msg_boot(UINT16 p, unsigned char *msg)

unsigned char *ptr;

PTR =消息;

while (*ptr !='\0')

sci_xmit_boot(p,*ptR);

PTR++;

}

}

void sci_xmit_boot(UINT16 p, unsigned char A)

如果(p == 0)

// while (SiaRegs.SCICTL2.bit.TXRDY ==0)//准备将另一个字符放入传输缓冲区

(SciaRegs.SCICTL2.bit.TXEMPTY ==0)//准备将另一个字符放入传输缓冲区

//等待上一个字符完成传输

//如果这花费的时间太长,则更改为中断驱动

}

SciaRegs.SCITXBUF =(A & 0x00FF);

}

否则,如果(p = 1)

// a = 0x55;

// while (ScibRegs.SCICTL2.bit.TXRDY == 0)

While (ScibRegs.SCICTL2.bit.TXEMPTY == 0)(时(ScibRegs.SCICTL2.bit.TXEMPTY == 0))

//等待上一个字符完成传输

}

ScibRegs.SCITXBUF =(A和0x00FF);

}

否则

//选择了错误的端口

}

}

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

    您应该更改设备的引导模式引脚,以便引导加载程序将循环等待输入...,然后连接到设备。

    请注意,在对密码位置进行编程时,闪存编程可能会中断。 在这种情况下,设备将永久锁定。

    此致,
    科迪

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

    科迪

    感谢您的回复,这很有效。

    我仍然不确定是什么导致它进入低功耗模式。 我想可能是在对密码位置进行编程时中断的。 但是,很难证明这一点。

    代码中有一个低功率模式功能。 我要做的是把它放在B到H区 这样,如果编程中断,它将减少该功能在意外情况下执行的可能性。

    Syed

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

    Syed,太棒了! 我很高兴您的设备能够正常工作!

    很可能指令只是编程中的一半,并且已损坏,因此 导致设备状态不佳。 我想,低功耗模式是该器件无法 通过JTAG进行通信的多种方式之一。

    您可以采取的一项措施是,在分支到应用程序代码之前,对引导加载程序检查的唯一代码或校验和进行编程,以帮助缓解此风险。 此校验和越接近最后编程越好。

    此致,
    科迪