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.

[参考译文] TMS570LC4357:通过 DMA 将数据从共享 RAM 传输到 EMIF

Guru**** 2455560 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1209144/tms570lc4357-transferring-data-from-shared-ram-to-emif-via-dma

器件型号:TMS570LC4357

您好!

我正在尝试使用 DMA 将数据从共享 RAM 中的缓冲区传输到 EMIF 地址。 根据(https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1046746/tms570lc4357-how-to-read-and-write-data-from-nvsram-using-the-emif-interface-via-dma)的示例、我尝试创建自己的用以下函数初始化 DMA 的类:

constexpr uint16_t Minor_frame_length {2048}; 
constexpr uint8_t  Major_frame_length {1};

// /**********************
// * Buffer Instantiation
// ***********************/
#pragma SET_DATA_SECTION(".sharedRAM")
    uint32_t major_frame_buffer[Minor_frame_length*Major_frame_length];
#pragma SET_DATA_SECTION()


void init(){

  // Set EMIF Addr
  this->EMIF_addr = (uint32_t*) (EMIF_Registers::EMIF_1_ADDR + EMIF_Registers::START_ADDR);   
  
  // Set DMA Contro packet   
  this->dma_control_packet.SADD = ((uintptr_t) &this->buffer[16]); /* source address, reading from shared RAM */
  this->dma_control_packet.DADD = (uintptr_t)this->EMIF_addr;  /* dst address, writing to EMIF addr of BRAM */
  this->dma_control_packet.ELCNT = 1; /* element count */
  this->dma_control_packet.FRCNT = 1; /* frame count */
  this->dma_control_packet.CHCTRL = 0; /*  Next channel to be triggered */
  this->dma_control_packet.ELDOFFSET = 0; /* element destination offset */
  this->dma_control_packet.ELSOFFSET = 0;
  this->dma_control_packet.FRDOFFSET = 0; /* frame destination offset   */
  this->dma_control_packet.FRSOFFSET = 0; /* frame source offset   */
  this->dma_control_packet.PORTASGN = PORTA_READ_PORTA_WRITE;  /* Read from shared RAM and write to EMIF */
  this->dma_control_packet.RDSIZE = ACCESS_16_BIT;
  this->dma_control_packet.WRSIZE = ACCESS_16_BIT;
  this->dma_control_packet.TTYPE = FRAME_TRANSFER; /* transfer type            */
  this->dma_control_packet.ADDMODEWR = ADDR_INC1; /* address mode write       */
  this->dma_control_packet.ADDMODERD = ADDR_FIXED; /* address mode read         */
  this->dma_control_packet.AUTOINIT = AUTOINIT_ON; /* autoinit                 */

  dmaSetCtrlPacket(this->dmaChannel, this->dma_control_packet);  
  
  // Set interrupt handlers
  dmaInterrupt_t dma_interrupt = BTC;
  dmaIrqHandler.setIrqHandler((void*) &dma_interrupt, this->dmaChannel, this);
  dmaEnableInterrupt(this->dmaChannel, dma_interrupt, DMA_INTA);
  dmaSetChEnable(this->dmaChannel, DMA_SW);
}

我尝试只是将一个16位从一个地址传输到另一个地址(元素计数= 1、帧计数= 1)、但未起作用。 EMIF 地址中的数据保持不变(0)。 此外、当我增加帧计数的数量、假设为2时、我停止接收来自 DMA 的 BTC 中断。 当我进行调试时、我可以看到 DMA 正在获得 BTC 中断、FIFO A (寄存器190)的目标地址以及 ChnTrCnt 不断移动。 但是、更改不会反映在存储器中。 我已经尝试更改读写大小、元素数量、帧数量和传输类型等多个参数、但没有成功地将一些数据写入 EMIF 寄存器。

如果有任何关于如何解决此问题的帮助或线索、我会很感激。

感谢你的帮助。

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

    您好、Georg:

    您的项目中是否启用了缓存?

    如果需要、您可以通过禁用一次来测试它吗?

    --

    谢谢。此致、
    Jagadish。

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

    Jagadish、您好!

    感谢你的帮助。 我已经尝试禁用缓存、但问题仍然存在。 然而,我在这个问题上取得了一些进展。
    当我在程序的 main 实例化我的类和缓冲器时、我填充缓冲区、然后启动传输、一切都很好。 我写入缓冲区的所有数据都通过 DMA 传输到 EMIF。 但是、当我在不同的任务中实例化我的类并在该任务中填充缓冲区时、微控制器仅将缓冲区的某些部分写入 EMIF 部分。 我注意到、如果我在填充缓冲区之前放置一个断点、并检查数据是否已写入缓冲区、传输将顺利进行。 尽管如此、当我在没有任何断点的情况下运行程序时、只有缓冲区的一部分被写入 EMIF。

    能否就如何解决这个问题提供一些建议?

    提前感谢。  

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

    您好、Georg:

    看起来您的项目涉及免费 RTOS 吗?

    当我在不同的任务实例化我的类并在该任务中填充缓冲区时,微控制器仅将缓冲区的一些部分写入 EMIF 部分

    任务在将所有数据填充到缓冲区之前似乎超时。 我们为什么不设置标志以确保在 DMA 启动传输之前填充所有数据。 只有在数据完全填满并设置标志后、才应启用 DMA。

    您能尝试一下吗?

    --

    谢谢。此致、
    Jagadish。