在线时间2 小时
UID3272401
注册时间2016-5-16
NXP金币0
该用户从未签到
新手上路

- 积分
- 16
- 最后登录
- 2016-5-20
|
dma对内存与内存之间一次性传送是没有问题的(通过软件直接触发传送),但是通过spi申请每次没把法触发dma。
一下是代码
spi初始化
SIM->SIM_SCGC6 |= (slave->bus ? SPI1_CLK_EN : SPI0_CLK_EN);
reg->MCR &= ~SPI_MDIS;
reg->MCR = SPI_HALT;
reg->MCR |= (SPI_MSTR | SPI_ROOE | SPI_PCSIS(0x1F));
slave->pushr = ®->PUSHR;
reg->MCR &= ~SPI_HALT;
spi申请传数
reg->MCR |= SPI_HALT;
reg->MCR |= (SPI_CLR_TXF | SPI_CLR_RXF);
reg->SR |= (SPI_TCF | SPI_EOQF | SPI_TFUF |
SPI_TFFF | SPI_RFOF | SPI_RFDF);
reg->RSER = (1 << 25) | (1 << 24);//配置RSER寄存器申请dma
reg->RSER |= (1 << 17) | (1 << 16);
reg->CTAR[0] = spi->priv;
dma配置:
edma_cfg_t prn_dma_config = {
.channelx = 1,
.peri_dmareq = SPI0_TRAN_DMAREQ,
.minor_loop_length = 48,
.trans_bytenum = 4,
.src_addr = NULL,
.src_size = DMA_SRC_32BIT,
.src_addr_inc = 0x04,
.src_adj_addr = 0,
.dest_addr = (SPI0_REG_BASE + 0x34),
.dest_size = DMA_DST_32BIT,
.dest_addr_inc = 0x00,
.dest_adj_addr = 0,
.dma_irqc = 0,
.dma_autoclose = 1,
};
prn_dma_config.src_addr = (uint32_t) &dprndata[0];
edma_config(&prn_dma_config);
void edma_config(edma_cfg_t *_config)
{
SIM->SIM_SCGC6 |= DMAMUX_CLK_EN;
SIM->SIM_SCGC7 |= DMA_CLK_EN;
/* 选择 通道x 配置外设的DMA Source Request Number */
DMAMUX->CHCFG[_config->channelx] = 0;
DMAMUX->CHCFG[_config->channelx] =
DMAMUX_CHCFG_SOURCE(_config->peri_dmareq);
DMAMUX->CHCFG[_config->channelx] |= DMAMUX_CHCFG_ENBL;
/* 打开通道x硬件DMA请求 */
DMAC->ERQ |= (1<<_config->channelx);
/*设置源地址信息*/
DMAC->TCD[_config->channelx].SADDR = _config->src_addr;
/* 在执行完针对源地址的操作之后,是否在原地址的基础上累加 */
DMAC->TCD[_config->channelx].SOFF = _config->src_addr_inc;
/* 先清零数据长度寄存器 */
DMAC->TCD[_config->channelx].ATTR = 0;
/* 设置源地址的传输宽度 */
DMAC->TCD[_config->channelx].ATTR |= _config->src_size;
/* 主的计数次数(major iteration count)达到后,是否重新更改源地址 */
DMAC->TCD[_config->channelx].SLAST = _config->src_adj_addr;
/* 设置目的地址信息 */
DMAC->TCD[_config->channelx].DADDR = _config->dest_addr;
/* 在执行完针对目的地址的操作之后,是否在原地址的基础上累加 */
DMAC->TCD[_config->channelx].DOFF = _config->dest_addr_inc;
/* 设置源地址的传输宽度 */
DMAC->TCD[_config->channelx].ATTR |= _config->dest_size;
/* 主的计数次数(major iteration count)达到后,是否重新更改目的地址 */
DMAC->TCD[_config->channelx].DLAST_SGA = _config->dest_adj_addr;
/* 设置数据长度,长度每次递减。
* 也可以称为 当前主循环计数器 current major loop count
*/
DMAC->TCD[_config->channelx].CITER_ELINKNO =
DMA_CITER_ELINKNO_CITER(_config->minor_loop_length);
/* 起始循环计数器,当主循环计数器为零的时候,将装载起始循环计数器的值 */
DMAC->TCD[_config->channelx].BITER_ELINKNO =
DMA_CITER_ELINKNO_CITER(_config->minor_loop_length);
/* 设置每一次传输字节的个数,个数达到上限时,DMA便将数据存入memory */
DMAC->TCD[_config->channelx].NBYTES_MLNO =
DMA_NBYTES_MLNO_NBYTES(_config->trans_bytenum);
DMAC->TCD[_config->channelx].CSR =0; /* 清空CSR的设置 */
if(!_config->dma_irqc) {
DMAC->INT &= ~(1 << _config->channelx); /* 关闭相应通道的中断请求 */
DMAC->TCD[_config->channelx].CSR &= ~DMA_CSR_INTMAJOR;/* 关闭DMA major_loop完成中断 */
}
else if(_config->dma_irqc == 1)
{
DMAC->INT |= (1 << _config->channelx); /* 开启相应通道的中断请求 */
DMAC->TCD[_config->channelx].CSR |= DMA_CSR_INTHALF;/* 使能DMA 主循环计数器减到一半 中断 */
}
else if(_config->dma_irqc == 2)
{
DMAC->INT |=(1 << _config->channelx); /* 开启相应通道的中断请求 */
DMAC->TCD[_config->channelx].CSR |= DMA_CSR_INTMAJOR ;/* 使能DMA 主循环计数器减到零 中断 */
}
if(!_config->dma_autoclose) {
DMAC->TCD[_config->channelx].CSR |= DMA_CSR_DREQ; /* 主循环计数器等于零后,自动关闭DMA */
}
else {
DMAC->TCD[_config->channelx].CSR &= (~DMA_CSR_DREQ); /* 主循环计数器等于零后,不关闭DMA */
}
return ;
}
如果通过软件
DMAC->TCD[chx].CSR |= (1 << 0); 直接启动dma的话spi的push寄存器还能接收到一次数据,之后在也接收不到了
|
|