DSPFlashLED以CCS3.3版本为例,介绍下关于DSP2812固化烧写的过程。
1.保证工程在RAM中调试完成;
2.配置好Flash.cmd文件,并加入工程;(CMD文件编写参考 ,Flash.cmd代码见附录1)
3.加入起始代码asm文件DSP281x_CodeStartBranch.asm;
4.配置C文件,并将初始化FLASH中的代码拷贝到RAM中运行;(C文件配置见附录2)
5.重新编译工程;
6.选择工具栏 Tools--F28xx On--Chip Flash Programmer,打开烧写工具,设置相关配置。
(1)首先设置 Clock configuration ,输入30,意思是晶振频率为30M,PLLCR 根据工程内的实际配置进行选择,一般为10,系统时钟SYSCLKOUT此时为150M;
(2)单击Flash Programmer Settings.选择设备 F2812,Selectversion to flash API 选择 FlashAPI-Interface2812V2_10.out.配置完成单机OK。
7.单击Execute Operation 开始烧写,烧写成功,断开仿真器,断电重启测试。
注意事项:
1. 一定要拔除仿真器(JTAG端),给电路板重新上电,方能实现FLASH启动。
2. 注意MP/MC引脚的电压。0为方式MC来作为计算机模式启动,3.3V为方式MP作为微处理器模式启动。
3. 由于GPIO引脚的F4F12F3F2决定了DSP2812的启动顺序,而从FLASH必须要在F4(SCITXDA)为1,而F12F3F2随意的状态下启动。请大家启动前确认F4引脚电压。
附录1:
Flash_Link.cmd
1 /*------------------------------------------*/ 2 /*描述:通过MEMORY伪指令来指示存储空间 */ 3 /*------------------------------------------*/ 4 5 MEMORY /* Program Memory */ 6 { 7 PAGE 0 : 8 FLASH : origin = 0x3D8000, length = 0x01FF80 /* on-chip FLASH */ 9 BEGIN : origin = 0x3F7FF6, length = 0x000002 10 ROM : origin = 0x3FF000, length = 0x000FC0 11 RESET : origin = 0x3FFFC0, length = 0x000002 12 13 VECTORS : origin = 0x3FFFC2, length = 0x00003E /* part of Boot ROM (MP/MCn=0) or XINTF zone 7 (MP/MCn=1) */ 14 RAML0 : origin = 0x008000, length = 0x001000 15 16 PAGE 1 : 17 RAMM0 : origin = 0x000000, length = 0x000400 /* on-chip RAM block M0 */ 18 RAMM1 : origin = 0x000400, length = 0x000400 /* on-chip RAM block M1 */ 19 RAML1 : origin = 0x009000, length = 0x001000 /* on-chip RAM block L1 */ 20 RAMH0 : origin = 0x3F8000, length = 0x002000 /* on-chip RAM block H0 */ 21 22 DEV_EMU : origin = 0x000880, length = 0x000180 /* device emulation registers */ 23 PIE_VECT : origin = 0x000D00, length = 0x000100 /* PIE Vector Table */ 24 FLASH_REGS : origin = 0x000A80, length = 0x000060 /* FLASH registers */ 25 CSM : origin = 0x000AE0, length = 0x000010 /* code security module registers */ 26 XINTF : origin = 0x000B20, length = 0x000020 /* external interface registers */ 27 CPU_TIMER0 : origin = 0x000C00, length = 0x000008 /* CPU Timer0 registers */ 28 CPU_TIMER1 : origin = 0x000C08, length = 0x000008 /* CPU Timer1 registers */ 29 CPU_TIMER2 : origin = 0x000C10, length = 0x000008 /* CPU Timer2 registers */ 30 PIE_CTRL : origin = 0x000CE0, length = 0x000020 /* PIE control registers */ 31 ECANA : origin = 0x006000, length = 0x000040 /* eCAN control and status registers */ 32 ECANA_LAM : origin = 0x006040, length = 0x000040 /* eCAN local acceptance masks */ 33 ECANA_MOTS : origin = 0x006080, length = 0x000040 /* eCAN message object time stamps */ 34 ECANA_MOTO : origin = 0x0060C0, length = 0x000040 /* eCAN object time-out registers */ 35 ECANA_MBOX : origin = 0x006100, length = 0x000100 /* eCAN mailboxes */ 36 SYSTEM : origin = 0x007010, length = 0x000020 /* System control registers */ 37 SPIA : origin = 0x007040, length = 0x000010 /* SPI registers */ 38 SCIA : origin = 0x007050, length = 0x000010 /* SCI-A registers */ 39 XINTRUPT : origin = 0x007070, length = 0x000010 /* external interrupt registers */ 40 GPIOMUX : origin = 0x0070C0, length = 0x000020 /* GPIO mux registers */ 41 GPIODAT : origin = 0x0070E0, length = 0x000020 /* GPIO data registers */ 42 ADC : origin = 0x007100, length = 0x000020 /* ADC registers */ 43 EVA : origin = 0x007400, length = 0x000040 /* Event Manager A registers */ 44 EVB : origin = 0x007500, length = 0x000040 /* Event Manager B registers */ 45 SCIB : origin = 0x007750, length = 0x000010 /* SCI-B registers */ 46 MCBSPA : origin = 0x007800, length = 0x000040 /* McBSP registers */ 47 CSM_PWL : origin = 0x3F7FF8, length = 0x000008 /* Part of FLASHA. CSM password locations. */ 48 } 49 50 /*------------------------------------------*/ 51 /*描述:设置堆栈值 */ 52 /*------------------------------------------*/ 53 -stack 400 54 55 /*------------------------------------------*/ 56 /*描述:通过SECTION伪指令来分配段到存储空间 */ 57 /*------------------------------------------*/ 58 59 SECTIONS 60 { 61 .reset : > RESET, PAGE = 0, TYPE = DSECT 62 vectors : > VECTORS, PAGE = 0, TYPE = DSECT 63 .cinit : > FLASH, PAGE = 0 64 .text : > FLASH, PAGE = 0 65 codestart : > BEGIN, PAGE = 0 66 67 ramfuncs: LOAD=FLASH, PAGE=0 68 RUN=RAML0,PAGE=0 69 LOAD_START(_RamfuncsLoadStart), 70 LOAD_END(_RamfuncsLoadEnd), 71 RUN_START(_RamfuncsRunStart) 72 73 .const : > FLASH, PAGE = 0 74 .econst : > FLASH, PAGE = 0 75 76 .data2 : > RAMM1, PAGE = 1 77 .stack : > RAMM0, PAGE = 1 78 .bss : > RAML1, PAGE = 1 79 .ebss : > RAML1, PAGE = 1 80 .sysmem : > RAMH0, PAGE = 1 81 .esysmem : > RAMH0, PAGE = 1 82 83 /* Allocate IQ math areas: */ 84 IQmath : > FLASH, PAGE = 0 /* Math Code */ 85 IQmathTables : > ROM, PAGE = 0, TYPE = NOLOAD /* Math Tables In ROM */ 86 87 88 PieVectTableFile : > PIE_VECT, PAGE = 1 89 90 /*** Peripheral Frame 0 Register Structures ***/ 91 DevEmuRegsFile : > DEV_EMU, PAGE = 1 92 FlashRegsFile : > FLASH_REGS, PAGE = 1 93 CsmRegsFile : > CSM, PAGE = 1 94 XintfRegsFile : > XINTF, PAGE = 1 95 CpuTimer0RegsFile: > CPU_TIMER0, PAGE = 1 96 CpuTimer1RegsFile: > CPU_TIMER1, PAGE = 1 97 CpuTimer2RegsFile: > CPU_TIMER2, PAGE = 1 98 PieCtrlRegsFile : > PIE_CTRL, PAGE = 1 99 100 /*** Peripheral Frame 1 Register Structures ***/ 101 ECanaRegsFile : > ECANA, PAGE = 1 102 ECanaLAMRegsFile : > ECANA_LAM PAGE = 1 103 ECanaMboxesFile : > ECANA_MBOX PAGE = 1 104 ECanaMOTSRegsFile: > ECANA_MOTS PAGE = 1 105 ECanaMOTORegsFile: > ECANA_MOTO PAGE = 1 106 107 /*** Peripheral Frame 2 Register Structures ***/ 108 SysCtrlRegsFile : > SYSTEM, PAGE = 1 109 SpiaRegsFile : > SPIA, PAGE = 1 110 SciaRegsFile : > SCIA, PAGE = 1 111 XIntruptRegsFile : > XINTRUPT, PAGE = 1 112 GpioMuxRegsFile : > GPIOMUX, PAGE = 1 113 GpioDataRegsFile : > GPIODAT PAGE = 1 114 AdcRegsFile : > ADC, PAGE = 1 115 EvaRegsFile : > EVA, PAGE = 1 116 EvbRegsFile : > EVB, PAGE = 1 117 ScibRegsFile : > SCIB, PAGE = 1 118 McbspaRegsFile : > MCBSPA, PAGE = 1 119 120 /*** Code Security Module Register Structures ***/ 121 CsmPwlFile : > CSM_PWL, PAGE = 1 122 123 }
附录2:将初始化Flash代码加载到RAM中运行(如果CSM已加密,则必须冲可加密的RAM块L0和L1中执行初始化Flash代码)
Flash_Link.cmd文件中,加载FLASH到RAM:
ramfuncs: LOAD=FLASH, PAGE=0
RUN=RAML0,PAGE=0
LOAD_START(_RamfuncsLoadStart),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart)
从FLASH中加载,在RAML0中运行,加载起始地址为_RamfuncsLoadStart,结束地址为_RamfuncsLoadEnd,运行起始地址为_RamfuncsRunStart。
main.c文件中,将初始化FLASH代码复制到RAM:
1 /*****************头文件********************/ 2 #include "DSP281x_Device.h" 3 #include "System.h" 4 5 /****************端口宏定义*****************/ 6 7 /****************常量宏定义*****************/ 8 9 /***************全局变量定义****************/ 10 11 /****************函数声明*******************/ 12 void DelayMs(int nms) 13 { 14 unsigned int i,j,k; 15 for (i = 0;i < 110;i++) 16 for(j = 0;j < 110;j++) 17 for(k = 0;k < nms;k++) 18 {} 19 } 20 21 /*------------------------------------------*/ 22 /*形式参数:void */ 23 /*返回值:void */ 24 /*函数描述:主函数 */ 25 /*------------------------------------------*/ 26 void main(void) 27 { 28 InitSysCtrl(); // 系统初始化子程序,在DSP28_sysctrl.c中 29 MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);//将初始化Flash代码复制到RAM 30 InitFlash();//初始化Flash 31 EALLOW; 32 GpioMuxRegs.GPADIR.all=0xff;//设置D1对应的DSP引脚为输出 33 GpioMuxRegs.GPBDIR.all=0;//设置D1对应的DSP引脚为输出 34 EDIS; 35 GpioDataRegs.GPADAT.all=0; 36 while(1) 37 { 38 //按键控制LED 39 /* if(GpioDataRegs.GPBDAT.bit.GPIOB1 == 0) */ 40 /* { */ 41 /* DelayMs(1); */ 42 /* GpioDataRegs.GPATOGGLE.bit.GPIOA0 = 1; */ 43 /* while(GpioDataRegs.GPBDAT.bit.GPIOB1 == 0); */ 44 /* } */ 45 /* */ 46 /* if(GpioDataRegs.GPBDAT.bit.GPIOB2 == 0) */ 47 /* { */ 48 /* DelayMs(1); */ 49 /* GpioDataRegs.GPATOGGLE.bit.GPIOA1 = 1; */ 50 /* while(GpioDataRegs.GPBDAT.bit.GPIOB2 == 0); */ 51 /* } */ 52 /* */ 53 /* if(GpioDataRegs.GPBDAT.bit.GPIOB3 == 0) */ 54 /* { */ 55 /* DelayMs(1); */ 56 /* GpioDataRegs.GPATOGGLE.bit.GPIOA2 = 1; */ 57 /* while(GpioDataRegs.GPBDAT.bit.GPIOB3 == 0); */ 58 /* } */ 59 /* */ 60 /* if(GpioDataRegs.GPBDAT.bit.GPIOB4 == 0) */ 61 /* { */ 62 /* DelayMs(1); */ 63 /* GpioDataRegs.GPATOGGLE.bit.GPIOA3 = 1; */ 64 /* while(GpioDataRegs.GPBDAT.bit.GPIOB4 == 0); */ 65 /* } */ 66 //流水灯 67 GpioDataRegs.GPADAT.all=0x0001;//D1对应输出低电平,发光二极管点亮 68 DelayMs(100); 69 GpioDataRegs.GPADAT.all=0x0002;//D1对应输出低电平,发光二极管点亮 70 DelayMs(100); 71 GpioDataRegs.GPADAT.all=0x0004;//D1对应输出低电平,发光二极管点亮 72 DelayMs(100); 73 GpioDataRegs.GPADAT.all=0x0008;//D1对应输出低电平,发光二极管点亮 74 DelayMs(100); 75 GpioDataRegs.GPADAT.all=0x0010;//D1对应输出低电平,发光二极管点亮 76 DelayMs(100); 77 GpioDataRegs.GPADAT.all=0x0020;//D1对应输出低电平,发光二极管点亮 78 DelayMs(100); 79 GpioDataRegs.GPADAT.all=0x0040;//D1对应输出低电平,发光二极管点亮 80 DelayMs(100); 81 GpioDataRegs.GPADAT.all=0x0080;//D1对应输出低电平,发光二极管点亮 82 DelayMs(100); 83 } 84 } 85 86 87 88 89
main.c
InitSysCtrl(); // 系统初始化子程序,在DSP28_sysctrl.c中
MemCopy(&RamfuncsLoadStart, &RamfuncsLoadEnd, &RamfuncsRunStart);//将初始化Flash代码复制到RAM
InitFlash();//初始化Flash
MemCopy将RamfuncsLoadStart作为源地址起始地址,RamfuncsLoadEnd作为源地址结束地址,将源地址数据复制到目的地址RamfuncsRunStart,从而实现将Flash代码复制到RAM中。
其中MemCopy函数在rts2800_ml.lib C支持库中定义。
DSP281x_GlobalPrototypes.h文件中定义所用变量:
DSP281x_GlobalPrototypes.h
1 #ifndef _System_H_ 2 #define _System_H_ 3 4 #ifdef __cplusplus 5 extern "C" { 6 #endif 7 8 //系统初始化相关函数声明 9 extern void InitSysCtrl(void); 10 extern void InitPieCtrl(void); 11 extern void InitPieVectTable(void); 12 extern void EnableInterrupts(void); 13 extern void InitSysCtrl(void); 14 extern void InitPll(Uint16 val); 15 extern void InitPeripheralClocks(void); 16 extern void KickDog(void); 17 extern void DisableDog(void); 18 extern Uint16 CsmUnlock(void); 19 extern void InitFlash(void); 20 21 extern void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr); 22 23 //声明外部变量,下面三个变量是链接器产生的全局变量 24 extern Uint16 RamfuncsLoadStart; 25 extern Uint16 RamfuncsLoadEnd; 26 extern Uint16 RamfuncsRunStart; 27 28 #ifdef __cplusplus 29 } 30 #endif 31 32 #endif
extern Uint16 RamfuncsLoadStart;
extern Uint16 RamfuncsLoadEnd;
extern Uint16 RamfuncsRunStart;
sysctrl.c文件中,flash初始化函数InitFlash()定义、ramfuncs定义。
1 #include "DSP281x_Device.h" 2 #include "System.h" 3 4 #pragma CODE_SECTION(InitFlash, "ramfuncs"); 5 6 /*------------------------------------------*/ 7 /*形式参数:void */ 8 /*返回值:void */ 9 /*函数描述:初始化系统 */ 10 /*------------------------------------------*/ 11 void InitSysCtrl(void) 12 { 13 DisableDog();//禁止看门狗 14 InitPll(0x8);//设置系统时钟=XCLKIN*8/2 15 InitPeripheralClocks(); //设置外设时钟 16 DINT; // 关闭总中断 17 IER = 0x0000; // 关闭外设中断 18 IFR = 0x0000; // 清中断标志 19 InitPieCtrl(); //初始化PIE控制寄存器 20 InitPieVectTable(); //使能PIE向量表 21 } 22 23 /*------------------------------------------*/ 24 /*形式参数:void */ 25 /*返回值:void */ 26 /*函数描述:禁止看门狗 */ 27 /*------------------------------------------*/ 28 void DisableDog(void) 29 { 30 EALLOW; 31 SysCtrlRegs.WDCR= 0x0068; 32 EDIS; 33 } 34 /*------------------------------------------*/ 35 /*形式参数:void */ 36 /*返回值:void */ 37 /*函数描述:喂看门狗 */ 38 /*------------------------------------------*/ 39 void KickDog(void) 40 { 41 EALLOW; 42 SysCtrlRegs.WDKEY = 0x0055; 43 SysCtrlRegs.WDKEY = 0x00AA; 44 EDIS; 45 } 46 /*------------------------------------------*/ 47 /*形式参数:void */ 48 /*返回值:void */ 49 /*函数描述:设置锁相环倍频系数 */ 50 /*------------------------------------------*/ 51 void InitPll(Uint16 val) 52 { 53 volatile Uint16 iVol; 54 55 if (SysCtrlRegs.PLLCR.bit.DIV != val) 56 { 57 58 EALLOW; 59 SysCtrlRegs.PLLCR.bit.DIV = val; 60 EDIS; 61 62 for(iVol= 0; iVol<4096; iVol++); 63 } 64 } 65 66 /*------------------------------------------*/ 67 /*形式参数:void */ 68 /*返回值:void */ 69 /*函数描述:初始化外设时钟 */ 70 /*------------------------------------------*/ 71 void InitPeripheralClocks(void) 72 { 73 EALLOW; 74 75 SysCtrlRegs.HISPCP.all = 0x0001;//设置高速时钟 2分频 76 SysCtrlRegs.LOSPCP.all = 0x0002;//设置低速时钟 4分频 77 78 //使能外围模块时钟 79 SysCtrlRegs.PCLKCR.bit.EVAENCLK=1; 80 SysCtrlRegs.PCLKCR.bit.EVBENCLK=1; 81 SysCtrlRegs.PCLKCR.bit.SCIAENCLK=1; 82 SysCtrlRegs.PCLKCR.bit.SCIBENCLK=1; 83 SysCtrlRegs.PCLKCR.bit.MCBSPENCLK=1; 84 SysCtrlRegs.PCLKCR.bit.SPIENCLK=1; 85 SysCtrlRegs.PCLKCR.bit.ECANENCLK=1; 86 SysCtrlRegs.PCLKCR.bit.ADCENCLK=1; 87 EDIS; 88 } 89 /*------------------------------------------*/ 90 /*形式参数:void */ 91 /*返回值:void */ 92 /*函数描述:初始化Flash */ 93 /*------------------------------------------*/ 94 void InitFlash(void) 95 { 96 EALLOW; 97 FlashRegs.FPWR.bit.PWR = 3; //设置Flash为正常工作状态 98 FlashRegs.FBANKWAIT.bit.RANDWAIT = 5;//设置随机存取等待时间 99 FlashRegs.FBANKWAIT.bit.PAGEWAIT = 5;//设置页面存取等待时间 100 FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF; //设置从睡眠到等待的转换时间 101 FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF; //设置从等待到激活的转换时间 102 FlashRegs.FOPT.bit.ENPIPE = 1; //使能流水线模式 103 EDIS; 104 asm(" RPT #7 || NOP");//软件延时,等待流水线刷新 105 } 106 107 /*------------------------------------------*/ 108 /*形式参数:void */ 109 /*返回值:状态值 */ 110 /*函数描述:unlocks the CSM */ 111 /*------------------------------------------*/ 112 #define STATUS_FAIL 0 113 #define STATUS_SUCCESS 1 114 115 Uint16 CsmUnlock() 116 { 117 volatile Uint16 temp; 118 119 // 写入密钥,应将0xFFFF替换成密钥值 120 EALLOW; 121 CsmRegs.KEY0 = 0xFFFF; 122 CsmRegs.KEY1 = 0xFFFF; 123 CsmRegs.KEY2 = 0xFFFF; 124 CsmRegs.KEY3 = 0xFFFF; 125 CsmRegs.KEY4 = 0xFFFF; 126 CsmRegs.KEY5 = 0xFFFF; 127 CsmRegs.KEY6 = 0xFFFF; 128 CsmRegs.KEY7 = 0xFFFF; 129 EDIS; 130 131 /// 执行空读 132 temp = CsmPwl.PSWD0; 133 temp = CsmPwl.PSWD1; 134 temp = CsmPwl.PSWD2; 135 temp = CsmPwl.PSWD3; 136 temp = CsmPwl.PSWD4; 137 temp = CsmPwl.PSWD5; 138 temp = CsmPwl.PSWD6; 139 temp = CsmPwl.PSWD7; 140 141 if (CsmRegs.CSMSCR.bit.SECURE == 0) 142 return STATUS_SUCCESS; 143 else 144 return STATUS_FAIL; 145 }
sysctrl.c
#pragma CODE_SECTION(InitFlash, "ramfuncs");
/*------------------------------------------*/
/*形式参数:void */
/*返回值:void */
/*函数描述:初始化Flash */
/*------------------------------------------*/
void InitFlash(void)
{
EALLOW;
FlashRegs.FPWR.bit.PWR = 3; //设置Flash为正常工作状态
FlashRegs.FBANKWAIT.bit.RANDWAIT = 5;//设置随机存取等待时间
FlashRegs.FBANKWAIT.bit.PAGEWAIT = 5;//设置页面存取等待时间
FlashRegs.FSTDBYWAIT.bit.STDBYWAIT = 0x01FF; //设置从睡眠到等待的转换时间
FlashRegs.FACTIVEWAIT.bit.ACTIVEWAIT = 0x01FF; //设置从等待到激活的转换时间
FlashRegs.FOPT.bit.ENPIPE = 1; //使能流水线模式
EDIS;
asm(" RPT #7 || NOP");//软件延时,等待流水线刷新
}
将InitFlash函数通过#program伪指令产生"ramfuncs"段,通过编译器将段的起始地址、结束地址及运行起始地址复制给RamfuncsLoadStart、RamfuncsLoadEnd、RamfuncsRunStart三个全局变量,在CMD文件指定地址于变量对应起来,在主函数中将Flash代码通过MemCopy函数复制到RAM中。
对于一些对时间敏感的代码也可加载到RAM中运行,以提高代码运行效率,方法可参考初始化Flash代码加载到RAM的操作。