1.28335XINTF外部接口介绍
28335外部接口XINTF采用非复用异步总线,可用于扩展SRAM、FLASH\ADC\DCA模块。XINTF接口分别映射到3个固定的存储器映射区域,模块信号如下图:
XINTF每个区域都有一个片选信号线,当对某个区域进行读/写访问时,将信号线置低
XINTF接口的访问时序是以内部时钟XTIMCLK为基准的,XTIMCLK信号频率可配置为系统时钟SYSCLKOUT的频率或一半。
XINTF接口信号如下表:
2.访问XINTF区域
CPU或CCS通过仿真器直接访问XINTF连接的外部存储器。XINTF的3个区域都有独立的片选信号线,并且各区域的读/写时许可以单独配置,当相应的片选信号线被选中(低电平有效)时,该区域被选中。
28335的地址总线为20位,采用统一寻址,被所有区域共用,总线上的地址由所要访问的具体区域决定:
区域0使用的外部地址范围为0x0000~0x00FFF,如果要对区域0的第一个存储单元进行操作,需要将0x0000送到地址线,并将片选信号XZCS0(低电平有效)拉低,如果要对区域0的最后一个存储单元进行操作,则将0x00FFF送到地址总线,并将区域0的片选信号线选中。
区域6与区域7的地址范围为0X0000~0XFFFFF,对这两个区域的操作与区域0相同。
3.写后读的流水线保护
28335在现实中执行的时许时读后写
假如要实现的功能为先向一个地址单元中写入数据,紧跟着从另一个地址单元中读取数据,但由于CPU的流水线操作,实际执行时,两条指令的顺序将翻转。因为流水线安排的问题,导致了读数据有可能不是实时更新的数据。
28335外设寄存器所在的存储单元都使用了硬件保护,以防止类似的访问时许翻转,保证写后读。XINTF的区域0具有写后读功能,区域0的读/写操作按照程序编写顺序执行。
28X的CPU会自动保护在同一存储器区域进行写后读操作,CPU会自动在原来读的操作指令后边插入空的时钟周期以便在读操作前完成写操作。
当外设通过XINTF连接映射时,写入一个寄存器也许会更新另外一个寄存器的状态位,写入第一个寄存器必须完成后,才能去读后边被更新的那个寄存器,因为读后写机制,如果读/写操作按照流水线的安排,就有可能读到一个错误的状态。采用区域0不会发生时许问题,但区域0通常不用来访问存储器,仅仅用来访问一些终端设备。其他区域与外设相连,若需要写后读的保护,可采用以下措施:
在写与读指令之间插入3个NOP指令,至少3个空指令才能保证代码分解后,流水线执行时,写操作在完成后读操作才会执行。
在写和读操作之间插入其他一些超过3个时钟周期的指令,保证写后读操作。
如果采用编译器的MV优化,就会自动在读写之间插入空指令,当这种时许操作只发生在外设映射到XINTF时的存储器访问。
4.XINTF的配置
在使用XINTF时,需要根据28335的实际工作频率、XINTF的时许特性以及外部设备或存储器的时许要求来进行设置。
(1)XINTF的配置程序
在XINTF配置或修改时钟寄存器的值期间,不允许程序中访问XINTF相关区域。这包括CPU流水线上的指令,XINTF写缓冲区的写访问,数据的读/写访问,数据的读/写,预取指令操作与DMA访问。为确定以上这些操作没有发生可遵循以下步骤:
确定DMA没有访问XINTF
按照下图修改XTIMING0/6/7、XINTCNF2或XBANK寄存器的值。
(2)时钟信号
XINTF模块使用两路时钟信号,XTIMCLK和XCLOUT这两路时钟信号与系统时钟信号SYSCLKOUT的关系如下图所示:
SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1;//开启XINTF时钟信号
//XINTF区域的所有访问操作都是基于XTIMCLK时钟为基准的
XintfRegs.XINTCNF2.bit.XTIMCLK = 1;//可将XTIMCLK 时钟频率设定为与SYSCLKOUT时钟频率相同或为其一半,默认情况为其一半。 1为一半/0为相同
//所有的XINTF的操作都有XCLKOUT的上升沿开始
XintfRegs.XINTCNF2.bit.CLKMODE = 1;//设定XCLKOUT的时钟频率和XTIMCLK相同或者一半,默认情况下为其一半,即为SYSCLKOUT时钟频率的1/4。
XintfRegs.XINTCNF2.bit.CLKOFF = 0;//1禁止XCLKOUT从引脚输出/0
(3)写缓冲器
默认情况下,写访问缓冲器是被禁止的, 为提高XINTF的性能,可使能写缓冲器。在没有停止CPU的情况下,最多允许3个数据通过缓冲器写入XINTF区域,缓冲器的深度可通过XINTCNF2寄存器配置。
(4)XINTF访问建立、有效、跟踪等待时间
XINTF区域的读写访问时许可分为3个部分;建立时间、有效时间及跟踪时间。通过配置每个区域的XTIMING寄存器可为该区域访问时许的3个部分设定相应值以XTIMCLK周期为最小单位,每个区域的读访问时许与写访问时许可以独立配置。为与低俗外部设备连接,可通过X2TIMING位将各部分等待时间延长一倍。
在XINTF访问建立期间,所选区域的片选信号被拉低,相应存储器的地址被发送到地址总线上,建立时间可通过本区域XTIMING寄存器进行配置,默认情况下,读/写访问都使用最大的建立时间,即6个XTIMCLK周期。
在XINTF访问有效期间内,可以访问中断设备,如果是读访问,则读选通信号XRD被拉低,数据被锁存到DSP中;如果是写访问,则写选通信号XWE0被拉低,数据被发送到数据总线上,如果该区域采用XREDAY信号,外部设备通过控制XREDAY信号可延长有效时间,此时有效时间可超过设定值,如果未使用XREDAY信号,总有效时间包含的XTIMCLK周期数即相应的XTIMING中的设定值再加1。默认情况下,读/写访问的有效时间为14个XTIMCLK周期。
在XINTF访问跟踪期间内,区域片选信号仍为低电平,但读/写选通信号拉置高电平,默认情况下,读/写访问都使用最大跟踪时间,即6个XTIMCLK周期。
在配置过程中需要考虑如下因素:
(1)读写访问3个阶段的最小等待时间要求
(2)XINTF的读/写时序
(3)外部存储器或设备的时许要求
(4)DSP器件与外部器件之间的附加延时
//XINTF访问的建立、有效、跟踪等待时间配置
XintfRegs.XTIMING6.bit.XWRLEAD = 1;
XintfRegs.XTIMING6.bit.XWRACTIVE = 2;
XintfRegs.XTIMING6.bit.XWRTRAIL = 1;
XintfRegs.XTIMING6.bit.XRDLEAD = 1;
XintfRegs.XTIMING6.bit.XRDACTIVE = 3;
XintfRegs.XTIMING6.bit.XRDTRAIL = 0;
5.区域的XREADY采样
如果XINTF模块采用XREADY采样功能,那么外设可扩展XINTF访问有效期间的时间。XINTF的所有区域共用一个XREDAY输入信号线,但每个区域可单独配置为使用或不使用XREDAY采样功能。每个区域的采样方式有两种:
(1)同步采样:同步采样中,XREDAY信号在总的有效时间结束前将保持一个XTIMCLK周期时间的有效电平。
(2)异步采样:异步采样中,XREDAY信号在总的有效时间结束前将保持3个XTIMCLK周期时间的有效电平。
//采样模式
XintfRegs.XTIMING7.bit.READYMODE = 0;//同步采样
无论哪种采样方式,如果采样到的XREDAY信号为低电平,访问阶段的有效时间将增加一个XTIMCLK时期,且在下一个XTIMCLK周期内将会对XREDAY信号重新采样,反复进行,直到采样到XREDAY为高电平。
若区域配置为XREDAY采样,则此区域的读/写访问均使用XREDAY采样功能,默认情况下,使用异步采样方式。使用XREDAY信号时,必须考虑XINTF最小等待时间的要求,采样方式不同最小等待时间也不同,主要取决于以下几点:
(1)XINTF固有的时序特性
(2)外部设备的时许要求
(3)DSP器件与外部器件之间的附加延时
(6).带宽
XINTF每个区域的数据总线都可以单独配置成16位或32位,XA0/XWE1引脚的功能在两种总线宽度下不同。当为16位总线模式时,XA0/XWE引脚引脚的功能为地址的最后一位XA0,如下图所示:
//采用16位总线模式时,可直接调用
InitXintf16Gpio();//InitXintf32Gpio();为32位总线模式
当为32位总线模式时, XA0/XWE引脚的功能为地字段的选通信号XWE1,如下图所示:
6.XINTF的DMA支持
7.XINTF的相关寄存器
(1)时许寄存器
时许寄存器各位信息以及功能描述如下表:
(2)XINTF配置寄存器XINTCNF2
XINTCNF2寄存器的各位信息如下表
28335的XINTF配置如下:
void xintf(void)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.XINTFENCLK = 1;//开启XINTF时钟信号
EDIS;
InitXintf16Gpio();//采用16位总线模式
EALLOW;
XintfRegs.XINTCNF2.bit.XTIMCLK = 1;//基准时钟
XintfRegs.XINTCNF2.bit.WRBUFF = 0;//无写缓冲器
XintfRegs.XINTCNF2.bit.CLKOFF = 0;//XCLKOUT使能
XintfRegs.XINTCNF2.bit.CLKMODE = 1;//XCLKOUT = XTIMCLK/2(默认)
//选择映射区域Zone6
//写时许配置
XintfRegs.XTIMING6.bit.XWRLEAD = 1;
XintfRegs.XTIMING6.bit.XWRACTIVE = 2;
XintfRegs.XTIMING6.bit.XWRTRAIL = 1;
//读时序配置
XintfRegs.XTIMING6.bit.XRDLEAD = 1;
XintfRegs.XTIMING6.bit.XRDACTIVE = 3;
XintfRegs.XTIMING6.bit.XRDTRAIL = 0;
XintfRegs.XTIMING6.bit.X2TIMING = 0;//实际值与寄存器中的设定值的比值0:比值为1:1
XintfRegs.XTIMING6.bit.USEREADY = 1;//XREADY信号采样
XintfRegs.XTIMING6.bit.READYMODE = 0;//同步采样
XintfRegs.XTIMING6.bit.XSIZE = 3;//16位总线模式
EDIS;
__asm(" RPT #7 || NOP");//会执行N+1次NOP指令,占用N+1个指令周期,也就是执行8次NOP指令
}
访问外部SRAM-DMA
28335为哈弗结构的DSP,哈弗结构是一种将程序指令存储和数据存储分开的存储器结构,即程序存储器和数据存储器是两个独立的存储器,每个存储器独立编址、独立访问。
28335的外部存储器可以映射到3个存储区域,即Zone0、Zone6、Zone7。
Zone0:0X004000~0X004FFF,4K×16位可编程最少一个等待周期。
Zone6:0X100000~0X1FFFFF,4K×16位10ns可编程最少一个等待周期。
Zone7:0X200000~0X2FFFFF,4K×16位70ns可编程最少一个等待周期。
将SRAM映射到Zone6
SRAM片选信号为低有效当地址线XA19 = 1;时片选到SRAM。地址线XA0~XA18 = 0;此时地址线信号用二进制表示 100 0000 0000 0000 0000转换为16进制为0X80000
由Zone6的基地址是0X100000可知SRAM的首地址为0X180000。
//选择映射区域
Uint16 *SRAM_ZONE(int zone)
{
if(zone = 0)
return = (Uint16 *)0x84000;
if(zone = 6)
return = (Uint16 *)0x180000;
if(zone = 7)
return = (Uint16 *)0x280000;
}
配置DMA向SRAM写入数据选择定时器0中断触发DMA
//SRAM数据写入
//DMA_Dest映射区域的地址DMA_Source写入的数据
void DMACH1_Init(Uint16 *DMA_Dest,Uint16 *DMA_Source)
{
EALLOW;
SysCtrlRegs.PCLKCR3.bit.DMAENCLK = 1; // 开启DMA时钟
EDIS;
ALLOW;
SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // 开启CPU Timer0
EDIS;
CpuTimer0Regs.TCR.bit.TSS = 1; //停止 Timer0
// Initialize DMA
DMAInitialize();
//配置DMA
DMACH1AddrConfig(DMA_Dest,DMA_Dest);//DMA_Dest目的地址DMA_Dest源地址
DMACH1BurstConfig(31,2,2);
//一次传输32个字,基于16-bit的字
//目的地址偏移2
//源地址偏移2
DMACH1TransferConfig(31,2,2);
//每传输32帧中断一次
//目的地址偏移2
//源地址偏移2
DMACH1WrapConfig(0xFFFF,0,0xFFFF,0);
DMACH1ModeConfig(DMA_TINT0,PERINT_ENABLE,ONESHOT_ENABLE,CONT_D
ISABLE,SYNC_DISABLE,SYNC_SRC,OVRFLOW_DISABLE,THIRTYTWO_BIT,CHINT_END,
CHINT_ENABLE);
StartDMACH1();
//Init the timer 0
CpuTimer0Regs.TIM.half.LSW = 512;
CpuTimer0Regs.TCR.bit.SOFT = 1; //计数器递减到0后定时器停止
CpuTimer0Regs.TCR.bit.FREE = 1;//CPU定时器仿真模式
CpuTimer0Regs.TCR.bit.TIE = 1; //CPU定时器中断标志位1:写1清0
CpuTimer0Regs.TCR.bit.TSS = 0; //开启Timer0
}
//SRAM读数据只需要修改 DMA_Dest和DMA_Source的位置
定时器0中断函数
查询中断向量表CPU定时器0位于PIE组1向量---复用CPU的INT1中断的INT1.7
DMA的通道
//定时器0中断请求
interrupt void TIM0_IRQn(void)
{
EALLOW;
PieCtrlRegs.PIEACK.bit.ACK7=1; //清除中断标志位
EDIS;
}
XINTF初始化
void xintf_init(void)
{
EALLOW;
PieVectTable.DINTCH1 = &TIM0_IRQn;//中断入口
EDIS;
//打开DMA的定时器中断通道
IER = M_INT7 ;
EnableInterrupts();
EINT;
xintf();//XINTF配置
}