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: Transferring data from shared RAM to EMIF via DMA

Part Number: TMS570LC4357

Hi,

I am trying to transfer data from a buffer located in shared RAM to an EMIF address using DMA. Based on the example from (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) I tried to create my own class that initializes the DMA with the following function:

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);
}

I tried just transferring a 16bits from one address to another one (Element count = 1, Frame Count = 1), but it didn't work. The data in the EMIF address remains the same (0). Also, when I increase the number of Frame Count, let's say to 2, I stop receiving the BTC interrupt from the DMA. When I debug, I can see that the DMA is getting the BTC interrupt and the destination address of the FIFO A (register 190) keeps moving as well as the ChnTrCnt. However, the change is not reflected in memory. I have tried changing several parameters like the read and write size, element count, frame count and transfer type but I have not managed to succeed on getting some data into the EMIF register.

I would appreciate any help or clue on how to fix this.

Thanks for your help.

  • Hi Georg,

    Is cache enabled in your project?

    If yes, can you please test it by disabling it once?

    --

    Thanks & regards,
    Jagadish.

  • Hi Jagadish,

    Thank you for your help. I already tried disabling the cache but the problem remains. However I had some progress with this issue.
    When I instantiate my class and buffer in the main of the program, I fill the buffer and then start the transfers, everything works perfectly. All data I write into the buffer is transferred via the DMA to the EMIF. However, when I instantiate my class in a different task and I fill up my buffer in this task, the microcontroller only writes some parts of the buffer into the EMIF section. I noticed that if I put a breakpoint just before filling the buffers and check that the data is written into the buffer, the transfers work without a problem. Nonetheless, when I run the program without any breakpoint, just some parts of the buffer are written into the EMIF.

    Could you please give me any suggestions on how to solve this problem?

    Thanks in advance. 

  • Hi Georg,

    Looks like your project involves Free RTOS right?

    when I instantiate my class in a different task and I fill up my buffer in this task, the microcontroller only writes some parts of the buffer into the EMIF section

    Looks like the task getting timeout before filling all the data into the buffer. Why don't we set a flag to make sure all the data filled before DMA initiating transfer. The DMA should be enabled only after data is completely filled and flag got set.

    Can you try this?

    --

    Thanks & regards,
    Jagadish.