在线时间0 小时
UID2044987
注册时间2013-9-28
NXP金币0
该用户从未签到
新手上路

- 积分
- 18
- 最后登录
- 1970-1-1
|
打算在内存和SPI2之间使用DMA,将内存中的数据通过DMA发送给SPI2,然后由SPI2发送出去。
将DMA和SPI2初始化之后,周期性地启动DMA(周期性调用dmaStart()函数)。

当前的问题是,每次启动DMA,只能够传输一小部分数据,相当大一部分数据会丢掉。按照代码中的设置,每次启动DMA,大概只有五分之一的数据DMA收到并发送了,一般最前面几个数据是正确的,后面便会丢失多个数据后有一个正确的数据被SPI2发送出去。我是通过逻辑分析仪来查看数据的。
芯片:MK60DN512VLQ10
开发环境:IAR 6.4 WORKBENCH,使用MQX的库twrk60d100m.
主要代码有SPI的初始化、DMA的初始化,以及DMA启动这几个函数。附在下文。
Void SPI_Init(void)
{
SPI_MemMapPtr BaseAdd = SPI2_BASE_PTR;
SIM_SCGC3 |= SIM_SCGC3_SPI2_MASK;
PORTD_PCR13 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK;//SOUT
PORTD_PCR12 = 0 | PORT_PCR_MUX(0x2) | PORT_PCR_DSE_MASK;//SCK
SPI_MCR_REG(BaseAdd) = 0
| SPI_MCR_CLR_TXF_MASK
| SPI_MCR_CLR_RXF_MASK
| SPI_MCR_PCSIS_MASK
| SPI_MCR_HALT_MASK
//| SPI_MCR_CONT_SCKE_MASK //continuous clock.
| SPI_MCR_MSTR_MASK;
SPI_CTAR_REG(BaseAdd,0) = 0
| SPI_CTAR_DBR_MASK
| SPI_CTAR_FMSZ(0x0F)
| SPI_CTAR_PDT_MASK//DELAY FACTOR IS 7
//| SPI_CTAR_PDT(0)
| SPI_CTAR_BR(0)
//| SPI_CTAR_CPOL_MASK
//| SPI_CTAR_CPHA_MASK
| SPI_CTAR_LSBFE_MASK
| SPI_CTAR_PBR(0);
SPI_SR_REG(BaseAdd) = SPI_SR_EOQF_MASK
//| SPI_SR_TFUF_MASK
| SPI_SR_TFFF_MASK
//| SPI_SR_RFOF_MASK
| SPI_SR_RFDF_MASK
;
SPI_RSER_REG(BaseAdd) = SPI_RSER_TFFF_RE_MASK | SPI_RSER_TFFF_DIRS_MASK
| SPI_RSER_RFDF_DIRS_MASK | SPI_RSER_RFDF_RE_MASK ;
SPI_MCR_REG(BaseAdd) &= ~SPI_MCR_HALT_MASK;
}
/*******************************
DMA的配置及初始化。
********************************/
void DMA_Init(void)
{
//时钟配置
SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK;//打开DMA通道多路复用器时钟
SIM_SCGC7 |= SIM_SCGC7_DMA_MASK;//打开DMA模块时钟
//通道配置,配置寄存器DMAMUX_CHCFG_REG:使能、触发、源设置
//通道有16个,源64个. 源21为SPI2发送。
DMAMUX_CHCFG5 = 0x00;//clear.
DMAMUX_CHCFG5 = DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_TRIG_MASK | DMAMUX_CHCFG_SOURCE(21);
//其他寄存器配置
DMA_CR = DMA_CR_EMLM_MASK | DMA_CR_CLM_MASK | DMA_CR_EDBG_MASK;//32位,CX(取消传输),EMLM(Enable minor loop mapping)
//DMA_ERQ = DMA_ERQ_ERQ5_MASK;//使能请求。enableDMA request n(0,1,2,。。。,15)。DMA相应通道的请求信号使能
DMA_CDNE = 0x05;//清除传输完成bit
DMA_CINT = 0x05;//清除中断
//TCD配置
DMA_TCD5_SADDR = (uint32)memForDMA1; //4 bytes.
DMA_TCD5_SOFF = 4; //源地址每次4个字节的偏移
DMA_TCD5_ATTR = DMA_ATTR_SSIZE(2) | DMA_ATTR_DSIZE(2); //传输宽度8 bits, 16 bits,32 bits,对应着0,1,2
DMA_TCD5_DADDR = (uint32)SPI2_BASE_PTR + 0x00000034; //PUSHR寄存器地址0x400AC034u。
DMA_TCD5_DOFF = 0;//目的地址要一直保持不变(PUSHR的地址)。
DMA_TCD5_DLASTSGA = 0; //最后一个地址后的目的地址处理。
DMA_TCD5_CSR = DMA_CSR_INTMAJOR_MASK; //major loop 完成后,产生一个中断。[ACTIVE][START][DONE][INT_MAJ][INT_HALF]
//添加DMA_CSR_BWC(2)后,每屏传到SPI上的数据增加了一些。
//添加DMA_CSR_INTHALF_MASK后似乎无影响。用于PING-PING buffer。
//DREQ bit is SET,then 主迭代完成时将ERQ位清零。
DMA_TCD5_CSR |= DMA_CSR_BWC(1) | DMA_CSR_DREQ_MASK;
//Minor loop mapping is enabled(CR[EMLM]=1) & Minor loop offset enabled(SMLOE or DMLOE=1)
DMA_TCD5_NBYTES_MLOFFYES = 1024;;//
DMA_TCD5_CITER_ELINKNO = 4; //current major interation count.当前主迭代剩余次数。
DMA_TCD5_BITER_ELINKNO = 4; //starting major interation count.与上一个变量的数值时钟相等。主迭代次数。
DMA_TCD5_SLAST = -4096; //到最后一个minor loop后的源地址处理处理
}
void DMA_Load(void)
{
DMAMUX_CHCFG5 &= ~DMAMUX_CHCFG_ENBL_MASK;//clear the ENBL bit.
DMAMUX_CHCFG5 |= DMAMUX_CHCFG_ENBL_MASK;
DMA_TCD5_CSR |= DMA_CSR_START_MASK;//(Should be written last after all other fields have been initialized)
}
Void dmaStart(void)
{
SPI_MemMapPtr BaseAdd = SPI2_BASE_PTR;
SPI_SR_REG(BaseAdd) = (SPI_SR_EOQF_MASK
| SPI_SR_TFUF_MASK
| SPI_SR_TFFF_MASK
| SPI_SR_RFOF_MASK
| SPI_SR_RFDF_MASK
);
SPI_MCR_REG(BaseAdd) |= SPI_MCR_CLR_RXF_MASK
| SPI_MCR_CLR_TXF_MASK;
DMA_Load();
}
|
|