This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC2652R7:DMA 软件传输中断问题

Guru**** 2846710 points
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1194636/cc2652r7-problems-on-dma-software-transfer-interrupt

器件型号:CC2652R7

尊敬的 E2E 团队:

我是 TI MCU 和 TI-RTOS 的初学者。

我正在尝试使用 DMA 软件传输。 DMA 模式为存储器散聚模式。
我使用调试器检查变量(代码中的"dst_buf")、内存到内存的传输成功。 "REQDONE"为1。

但是、DMA 传输完成中断不会发生。
我不确定我的代码的问题在哪里、我也不知道如何调试它。

这是我的参考代码。 期待您的回复。
此代码仅为 DMA 软件传输测试部分。 在另一个部分中、使用 DMA + UART、其他硬件中断等。

此致、

#include <ti/drivers/dpl/HwiP.h>
#include <ti/drivers/dma/UDMACC26XX.h>
#include <ti/sysbios/knl/Task.h>

#define INT_DMA_DONE_COMB_PRI       (2 << 5)        /* 7=Lowest / 1=Highest */

static UDMACC26XX_Handle    handle;
static uint32_t             base_addr;
static uint8_t              src_buf[24], dst_buf[24];
static tDMAControlTable     MyTaskList[2];
static Task_Struct          task_struct;
static Char                 task_stack[768];

static void task_exec(void);
static void hal_dma_complete_intr(uintptr_t arg);

void hal_dma_init(void)
{
    HwiP_Params                 hwi_params;
    Task_Params                 task_params;
    UDMACC26XX_HWAttrs const    *p_hw_attrs;
    uint32_t                    i;

    handle = UDMACC26XX_open();
    p_hw_attrs = handle->hwAttrs;
    base_addr = p_hw_attrs->baseAddr;

    HwiP_Params_init(&hwi_params);
    //hwi_params.priority = INT_DMA_DONE_COMB_PRI;
    HwiP_create(INT_DMA_DONE_COMB, hal_dma_complete_intr, NULL/*&hwi_params*/);

    Task_Params_init(&task_params);
    task_params.stackSize = sizeof(task_stack);
    task_params.stack = task_stack;
    task_params.priority = 1;
    Task_construct(&task_struct, (Task_FuncPtr)task_exec, &task_params, NULL);

    for(i = 0; i < sizeof(src_buf); i++)
    {
        src_buf[i] = i + 1;
        dst_buf[i] = 0;
    }
}

void hal_dma_enable(uint8_t ch)
{
    UDMACC26XX_channelEnable(handle, (uint32_t)(0x01) << ch);
}

void hal_dma_disable(uint8_t ch)
{
    UDMACC26XX_channelDisable(handle, (uint32_t)(0x01) << ch);
}

void hal_dma_scatter_gather(uint8_t ch, uint32_t task_cnt, void *p_task_list)
{
    hal_dma_disable(ch);
    uDMAChannelScatterGatherSet(base_addr, ch, task_cnt, p_task_list, false);
    hal_dma_enable(ch);
    uDMAChannelRequest(base_addr, ch);
}

static void task_exec(void)
{
    uint32_t    i;

    while(1)
    {
        for(i = 0; i < sizeof(src_buf); i++)
        {
            dst_buf[i] = 0;
        }

        MyTaskList[0].pvSrcEndAddr = &src_buf[2];
        MyTaskList[0].pvDstEndAddr = &dst_buf[2];
        MyTaskList[0].ui32Control = UDMA_SRC_INC_8 | UDMA_DST_INC_8 | UDMA_SIZE_8 | UDMA_ARB_1 | (((3) - 1) << 4) | UDMA_MODE_MEM_SCATTER_GATHER | UDMA_MODE_ALT_SELECT;
        MyTaskList[0].ui32Spare = 0;

        MyTaskList[1].pvSrcEndAddr = &src_buf[23];
        MyTaskList[1].pvDstEndAddr = &dst_buf[23];
        MyTaskList[1].ui32Control = UDMA_SRC_INC_8 | UDMA_DST_INC_8 | UDMA_SIZE_8 | UDMA_ARB_1 | (((3) - 1) << 4) | UDMA_MODE_AUTO;
        MyTaskList[1].ui32Spare = 0;

        hal_dma_scatter_gather(0, sizeof(MyTaskList) / sizeof(tDMAControlTable), MyTaskList);

        Task_sleep(1000 * 1000);
    }
}

static void hal_dma_complete_intr(uintptr_t arg)
{
    uDMAIntClear(base_addr, (uint32_t)(0x01) << 0);
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yuya、

    代码中缺少一些 API、例如 uDMAControlBaseSet、 uDMAChannelControlSet 和 uDMAChannelEnable。  您还需要使用 uDMAChannelTransferSet、并且可以使用 uDMAChannelModeGet 检查现有的传输模式。  请进一步查看 UDMA DriverLib 文档 、并考虑参考 ADC、SPI 和 UART2 TI 驱动程序使用的 UDMACC26XX 功能。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ryan、

    感谢你的答复。

    我指的是 UDMACC26XX 和 UDMA 驱动程序库。

    --
    第24行
    Handle = UDMACC26XX_OPEN ();

    第58行
    uDMAChannelScatterGatherSet (base_addr、ch、task_cnt、p_task_list、false);
    --

    内存到内存的传输成功。 "REQDONE"为1。
    但是、DMA 传输完成中断不会发生。

    我的代码中是否缺少中断 API 或 TI-RTOS API?

    此致、
    尤雅

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已经介绍了一些关于缺少 API 的想法、  uDMAIntRegister 可能是另一个想法。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我想没有缺少 API。

    uDMAControlBaseSet
    ->它在 UDMACC26XX_open 中调用。

    uDMAChannelEnable
    ->I use UDMACC26XX_channelEnable。 两者都是等效的。

    uDMAChannelControlSet
    uDMAChannelTransferSet
    ->I use uDMAChannelScatterGatherSet。 使用"pvTaskList"参数设置控制表。
    内存到内存的传输成功。

    uDMAIntRegister
    ->我在"Hwip_create"之后添加了它,并调用了异常处理程序。 我不知道为什么。

    您可以给我提供"TI-RTOS + UDMA 软件传输+中断"的示例源吗?
    我想与正确工作的代码进行比较。

    此致、
    尤雅

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我解决了这个问题。
    我需要调用 uDMAIntSwEventEnable。

    此致、
    尤雅