查看: 2414|回复: 3

[求助] 求解! k21 spi-dma问题

[复制链接]

该用户从未签到

2

主题

3

帖子

0

新手上路

Rank: 1

积分
16
最后登录
2016-5-20
发表于 2016-5-19 11:56:56 | 显示全部楼层 |阅读模式


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 = &reg->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寄存器还能接收到一次数据,之后在也接收不到了

我知道答案 目前已有3人回答
回复

使用道具 举报

该用户从未签到

712

主题

6371

帖子

0

超级版主

Rank: 8Rank: 8

积分
24871
最后登录
2025-7-18
发表于 2016-5-19 15:37:02 | 显示全部楼层
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

3

帖子

0

新手上路

Rank: 1

积分
16
最后登录
2016-5-20
 楼主| 发表于 2016-5-19 19:57:42 | 显示全部楼层
小恩GG 发表于 2016-5-19 15:37
请参考此经验贴介绍:
https://www.nxpic.org.cn/module/forum/thread-582281-1-1.html

谢谢,提供资料,我有个问题问你一下,spi向dma发送传数据的请求,这个请求是通过硬件完成的,我想知道这个请求的硬件线路是需要我们操作某个引脚配置还是cpu内部有条线路发生这个请求
回复 支持 反对

使用道具 举报

该用户从未签到

712

主题

6371

帖子

0

超级版主

Rank: 8Rank: 8

积分
24871
最后登录
2025-7-18
发表于 2016-5-20 10:01:37 | 显示全部楼层
syrd 发表于 2016-5-19 19:57
谢谢,提供资料,我有个问题问你一下,spi向dma发送传数据的请求,这个请求是通过硬件完成的,我想知道这 ...

无需额外的引脚配置的,是在MCU内部完成触发过程的
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-7-19 15:07 , Processed in 0.092961 second(s), 22 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表