查看: 1333|回复: 3

[已解决] LPC828 的DMA传输字节限制问题

[复制链接]
  • TA的每日心情
    开心
    2021-10-26 17:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    1

    主题

    4

    帖子

    0

    注册会员

    Rank: 2

    积分
    71
    最后登录
    2022-12-19
    发表于 2021-10-22 16:51:29 | 显示全部楼层 |阅读模式
    本帖最后由 小恩GG 于 2021-11-11 16:15 编辑

    由于我需要通过SPI串口给灯带传输RGB值,一共有54个灯珠。刷新一次灯珠值需要54*24=1296个字节,但是DMA好像最大只能传输1KB;不知道如何能够一次传输1296字节;求大佬解答;目前我还没有玩过NXP芯片;
    下面是代码:
    static bool dmaTXSend(uint16_t *data, int bytes)
    {
            /* Disable the DMA IRQ to prevent race conditions with shared data */
            NVIC_DisableIRQ(DMA_IRQn);

            /* This is a limited example, limit descriptor and byte count */
            if ((countTXDescUsed >= SPITXDESC) || (bytes > 1296)) {
                    /* Re-enable the DMA IRQ */
                    NVIC_EnableIRQ(DMA_IRQn);

                    /* All DMA descriptors are used, so just exit */
                    return false;
            }
            else if (countTXDescUsed == 0) {
                    /* No descriptors are currently used, so take the first one */
                    nextTXDesc = 0;
            }
            
            /* This is a limited example, limit descriptor and byte count */
            if ((countTXDescUsed2 >= SPITXDESC) || (bytes > 1296)) {
                    /* Re-enable the DMA IRQ */
                    NVIC_EnableIRQ(DMA_IRQn);

                    /* All DMA descriptors are used, so just exit */
                    return false;
            }
            else if (countTXDescUsed2 == 0) {
                    /* No descriptors are currently used, so take the first one */
                    nextTXDesc2 = 0;
            }

            /* Create a descriptor for the data */
            dmaTXDesc[countTXDescUsed].source = DMA_ADDR(data + bytes - 1);        /* Last address here */
            dmaTXDesc[countTXDescUsed].dest = DMA_ADDR(&LPC_SPI0->TXDAT);        /* 2Byte aligned */
            
            /* Create a descriptor for the data */
            dmaTXDesc2[countTXDescUsed2].source = DMA_ADDR(data + bytes - 1);        /* Last address here */
            dmaTXDesc2[countTXDescUsed2].dest = DMA_ADDR(&LPC_SPI1->TXDAT);        /* 2Byte aligned */

            /* If there are multiple buffers with non-contiguous addresses, they can be chained
               together here (it is recommended to only use the DMA_XFERCFG_SETINTA on the
               last chained descriptor). If another TX buffer needs to be sent, the DMA
               IRQ handler will re-queue and send the buffer there without using chaining. */
            dmaTXDesc[countTXDescUsed].next = DMA_ADDR(0);
            
            dmaTXDesc2[countTXDescUsed2].next = DMA_ADDR(0);

            /* Setup transfer configuration */
            dmaTXDesc[countTXDescUsed].xfercfg = DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA |
                                                                                     DMA_XFERCFG_SWTRIG | DMA_XFERCFG_WIDTH_16 | DMA_XFERCFG_SRCINC_1 |
                                                                                     DMA_XFERCFG_DSTINC_0 | DMA_XFERCFG_XFERCOUNT(bytes);
            
            dmaTXDesc2[countTXDescUsed2].xfercfg = DMA_XFERCFG_CFGVALID | DMA_XFERCFG_SETINTA |
                                                                                     DMA_XFERCFG_SWTRIG | DMA_XFERCFG_WIDTH_16 | DMA_XFERCFG_SRCINC_1 |
                                                                                     DMA_XFERCFG_DSTINC_0 | DMA_XFERCFG_XFERCOUNT(bytes);

            /* If a transfer is currently in progress, then stop here and let the DMA
               handler re-queue the next transfer. Otherwise, start the transfer here. */
            if (countTXDescUsed == 0) {
                    /* Setup transfer descriptor and validate it */
                    Chip_DMA_SetupTranChannel(LPC_DMA, DMAREQ_SPI0_TX, &dmaTXDesc[countTXDescUsed]);

                    /* Setup data transfer */
                    Chip_DMA_SetupChannelTransfer(LPC_DMA, DMAREQ_SPI0_TX,
                                                                              dmaTXDesc[countTXDescUsed].xfercfg);

                    Chip_DMA_SetValidChannel(LPC_DMA, DMAREQ_SPI0_TX);
    //                Chip_DMA_SetTrigChannel(LPC_DMA, DMAREQ_SPI0_TX);
            }
            
            if (countTXDescUsed2 == 0) {
                    /* Setup transfer descriptor and validate it */
                    Chip_DMA_SetupTranChannel(LPC_DMA, DMAREQ_SPI1_TX, &dmaTXDesc2[countTXDescUsed2]);

                    /* Setup data transfer */
                    Chip_DMA_SetupChannelTransfer(LPC_DMA, DMAREQ_SPI1_TX,
                                                                              dmaTXDesc2[countTXDescUsed2].xfercfg);

                    Chip_DMA_SetValidChannel(LPC_DMA, DMAREQ_SPI1_TX);
    //                Chip_DMA_SetTrigChannel(LPC_DMA, DMAREQ_SPI1_TX);
            }

            /* Update used descriptor count */
            countTXDescUsed++;
            
            countTXDescUsed2++;

            /* Re-enable the DMA IRQ */
            NVIC_EnableIRQ(DMA_IRQn);

            return true;
    }

    最佳答案

    楼主您好, 这个1024 个传输,并不一定是1024字节,这个具体几个字节取决于WIDTH 的配置。 关于SPI-DMA, 可以参考SDK下面demo.

    寄存器配置说明

    寄存器配置说明
    终于解决了问题
    回复

    使用道具 举报

    该用户从未签到

    656

    主题

    6312

    帖子

    0

    超级版主

    Rank: 8Rank: 8

    积分
    20028
    最后登录
    2024-4-26
    发表于 2021-10-26 16:45:10 | 显示全部楼层
    楼主您好,
    这个1024 个传输,并不一定是1024字节,这个具体几个字节取决于WIDTH 的配置。

    关于SPI-DMA, 可以参考SDK下面demo.
    123.png
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2021-10-26 17:07
  • 签到天数: 2 天

    [LV.1]初来乍到

    1

    主题

    4

    帖子

    0

    注册会员

    Rank: 2

    积分
    71
    最后登录
    2022-12-19
     楼主| 发表于 2021-10-26 16:57:10 | 显示全部楼层
    小恩GG 发表于 2021-10-26 16:45
    楼主您好,
    这个1024 个传输,并不一定是1024字节,这个具体几个字节取决于WIDTH 的配置。

    首先感谢小恩,这个问题自己摸索解决了;需要通过link to next descriptor方式连接下一个通道描述,也就是通过分两次传输超过1024字的源数据;xfercfg这个配置要加上DMA_XFERCFG_RELOAD;
    1635238564(1).jpg
    终于解决了问题
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-4-10 22:38
  • 签到天数: 1335 天

    [LV.10]以坛为家III

    88

    主题

    4292

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    9049
    最后登录
    2024-4-13
    发表于 2021-10-27 14:36:12 | 显示全部楼层
    学习了
    我还以为只能两次触发呢

    谢谢楼主分享经验
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-26 21:18 , Processed in 0.131636 second(s), 26 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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