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.

[参考译文] TM4C123GH6PM:TM4C 和 UDMA

Guru**** 2524290 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1001159/tm4c123gh6pm-tm4c-and-udma

器件型号:TM4C123GH6PM

Howdy、

我正在尝试将具有 Tivaware 的 TM4C 上的端口 D 用作数字输出端口、其中存储了要写入的数据。 当计时器1A 到期时、数据应从 wavex.array (uint8_t 数组)一次传输一个字节到端口 D 位带地址(位0至5)、传输时间应以数组的大小为单位(wavex.size)。 目标是使用极少的 CPU 以硬件定时精度将波形输出到端口 D 位0至5、直到波形阵列耗尽。  

我的最新尝试嵌入在帖子中。  计时器工作正常、我可以通过检查中断函数(未显示)来验证它是否工作、但在"UDMA_ERROR"函数中出现未指定的错误。

问题:

  • 使用 UDMA 是否可以实现目标?
  • 如何确定发生错误以外的 uDMA 错误?
  • Tivaware 和 TM4C 文档中的通道设置令人困惑、我是否使用 GPIO D 通道或 Timer A 通道? 似乎也不起作用。

#define MDI_V2_DAC       (*((volatile unsigned long *)0x400070FC)) // Port D bits 5-0    
    
void udma_error(){
    uint32_t error = uDMAErrorStatusGet();
    uDMAErrorStatusClear();
}
    
void udma_timer_test(){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_TIMER1))
    {
    }

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);

    while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA))
    {
    }

    uDMAEnable();

    uDMAControlBaseSet(dma_table);

    uDMAChannelAttributeDisable(UDMA_CHANNEL_TMR1A, 0);

    uDMAIntRegister(INT_UDMAERR, udma_error);

    //This configure the DMA to fire when Timer 1A times out, and increments the
    //memory to increment by 8 bytes, and the destination (GPIO to not change).
    //In short, when Timer 1A expires, it outputs a new value to the GPIO
    uDMAChannelControlSet(UDMA_CHANNEL_TMR1A | UDMA_PRI_SELECT,
                          UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_1);

    //Configure Timer 0 to be split pair timer, with timer A counting up
    TimerConfigure(TIMER1_BASE, (TIMER_CFG_A_PERIODIC | TIMER_CFG_SPLIT_PAIR | TIMER_CFG_B_PERIODIC));

    //TimerIntRegister(TIMER1_BASE, TIMER_A, mdi_waveform_interrupt);

    //Increment on pos edge of the clock
    TimerControlEvent(TIMER1_BASE, TIMER_A, TIMER_EVENT_POS_EDGE);
    
    uDMAChannelTransferSet(UDMA_CHANNEL_TMR1A | UDMA_PRI_SELECT,
                    UDMA_MODE_BASIC, waveform.array, MDI_V2_DAC,
                    waveform.size);

    //Enable the timer interrupt
    TimerIntEnable(TIMER1_BASE, TIMER_TIMA_TIMEOUT);

    //Set that Timer 1A timeout triggers a DMA
    TimerDMAEventSet(TIMER1_BASE, TIMER_DMA_TIMEOUT_A);

    //Enable DMA for Timer 1A
    uDMAChannelEnable(UDMA_CHANNEL_TMR1A);

    //Enable the timer
    TimerEnable(TIMER1_BASE, TIMER_A);
}

感谢您的任何帮助!

奥斯汀

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

    UDMA 返回的唯一错误是总线或存储器保护错误。 这意味着 UDMA 尝试读取或写入不存在或受保护的存储器位置。

    您是否使用外部时钟使 Timer1A 递增? 什么是 frequnecy? 如果使用定时器来生成 UDMA 请求、请使用定时器通道。 由于 UDMA 必须仲裁 RAM 的读取、写入时序仍会有一些抖动。 CPU 具有优先级、UDMA 偶尔会被挂起一个周期。

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

    嗨、Bob、

    感谢您提供有关错误的信息、我将仔细检查地址、以确保它们正确无误。 当使用基于中断的方法时、它们似乎工作正常、但这种方法不够快。

    Timer1A 由80MHz 的内部时钟驱动。  

    除了 Tivaware 文档外、是否还有其他示例显示为 UDMA 配置的一些不同外设?  

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

    这里是两个 uDMA 项目。 一个读取 ADC、另一个读取 SSI.e2e.ti.com/.../5518.udma_5F00_demo_5F00_SSI.zipe2e.ti.com/.../0045.ADCwDMA.zip

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

    嗨、Bob、

    很抱歉耽误你的回答。 我查看了这些示例、但仍然无法让 DMA 处理我的用例。

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

    我在您发布的代码中没有定义的值。  您能否将项目导出到.zip 文件并将其附加到此主题上的帖子?