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.

[参考译文] MSP430FR6007:在 20 位地址空间中使用 DMA 失败

Guru**** 2690845 points

Other Parts Discussed in Thread: MSP430FR6007

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1598773/msp430fr6007-dma-usage-in-20bit-address-room-fails

器件型号: MSP430FR6007

您好!

我谈到这个主题、很遗憾、 论坛已经结束:MSP430FR6007:crc_table function - MSP 低功耗微控制器论坛 — MSP 低功耗微控制器 — TI E2E 支持论坛 

 

我现在把它煮到 20 位地址室,当 Im 64kb 地址室与 CRC 模块相关时,我的 DMA 输入器工作,

不幸的是、当我进入扩展地址室 0x10000 时、它会杀死系统:

基本问题:MSP430FR6007 DMA 模块是否支持扩展地址空间?

    DMA_initParam cfg = {
        DMA_CHANNEL_0,                 // channelSelect
        DMA_TRANSFER_BLOCK,            // transferModeSelect
        static_cast<uint16_t>(length), // transferSize
        DMA_TRIGGERSOURCE_0,           // triggerSourceSelect
        DMA_SIZE_SRCBYTE_DSTBYTE,      // transferUnitSelect
        DMA_TRIGGER_RISINGEDGE         // triggerTypeSelect
    };

    DMA_init(&cfg);

    // Use proper 20-bit address handling
    // Convert pointers to 32-bit first to avoid truncation
    uint32_t volatile src_addr = reinterpret_cast<uint32_t>(src);
    uint32_t volatile dst_addr = reinterpret_cast<uint32_t>(dst);

    // Set the Source Address (20-bit)
    __data20_write_long((uint32_t)&DMA0SA, src_addr & 0xFFFFF);

    // Reset bits before setting them
    HWREG16(DMA_BASE + DMA_CHANNEL_0 + OFS_DMA0CTL) &= ~(DMASRCINCR_3);
    HWREG16(DMA_BASE + DMA_CHANNEL_0 + OFS_DMA0CTL) |= DMA_DIRECTION_INCREMENT;

    // Set the Destination Address (20-bit)
    __data20_write_long((uint32_t)&DMA0DA, dst_addr & 0xFFFFF);

    HWREG16(DMA_BASE + DMA_CHANNEL_0 + OFS_DMA0CTL) &= ~(DMADSTINCR_3);
    HWREG16(DMA_BASE + DMA_CHANNEL_0 + OFS_DMA0CTL) |= (DMA_DIRECTION_UNCHANGED << 2);

    // Clear DMA interrupt flag and start transfer
    DMA0CTL &= ~DMAIFG;
    DMA_enableTransfers(DMA_CHANNEL_0);
    DMA_startTransfer(DMA_CHANNEL_0);

    // Poll for completion
    while (!(DMA0CTL & DMAIFG))
    {
      __no_operation();
    }

    DMA_disableTransfers(DMA_CHANNEL_0);

 

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

    DMA 硬件支持 20 位地址。 问题是编译器是否会为__data20_write_long 生成适当的指令?

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

    反汇编___data20_write_long。 看起来还不错

    0x0001373a    1e 41 0a 00       mov    10(r1), r14      ;@>0000a
    0x0001373e    1f 41 0c 00       mov    12(r1), r15      ;@>0000c
    0x00013742    3e f3             and    #-1, r14         ;r3 As==11
    0x00013744    3f f0 0f 00       and    #15, r15         ;#0x000f
    0x00013748    8d 00 12 05       mova   r13, 1298        ;0x0512
    0x0001374c    8d 4e 00 00       mov    r14, 0(r13)      ;
    0x00013750    8d 4f 02 00       mov    r15, 2(r13)      ;

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

    不对、这是错误的。

    我被使用 R13 抛出,但事实证明,反汇编是不正确的。 0x008d 不是从寄存器移至绝对值、而是从加载立即执行。  

    因此、这会将一个 20 位地址加载到 R13 中(只需要 16 个地址)、然后使用两个 16 位写入 DMA0SA。 这些发生的顺序无关紧要、高 16 位将为零。

    使用 GCC、我可以使用__data16_write_addr () 获得更好的结果。

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

    好地方、 使用__data16_write_addre () 进行的首次测试很有前景。 我将进一步深入了解。 我将在测试完成后关闭此项。 感谢您的观看。  

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

    内在函数支持函数的 GCC 文档很薄、因此我寻找了更多。 slau132 没有提供更多信息、但它包含生成的代码示例。

    表明 data20 函数与 DMA 地址寄存器无关。