Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
19 years ago

problem about data transmission using DMA

Hi Every one:

I am writing a program that requires iterative access to image data which I placed on SD-ram (as on-chip memory is not big enough)

I figured that the program can probably run somehow faster if I gets a DMA controller to read these image data from SDRAM to buffers that I placed on the on-chip memory and then process the data on on-chip memory instead of processing data on SDRAM.

I wrote a function which opens up a DMA channel and carries out a DMA transaction and close the channel. I tested the function one DMA transaction one by one and verified the copied data to be exactly the same.

But when I later integrated this function into my program which iteratively calls this DMA transmission function to transmit different section of an image from SD RAM to a fixed memory address on on-chip memory . I found out that the copied data are partially corrupted (some part of them are correctly copied but some data are corrupted in chunks) when I verified the copied data.

I thought it was because i didn't close the channel properly, but this stil happens when i close both transmission and receiving channel at the end of the DMA function

Anyone encountered similar problem? or have any idea how to solve it??

I attached the code of the DMA function below incase anyone is interested

Thank you

Tony

void DMATransfer(int x,int y)
{
  //
  alt_dma_txchan txchan;
  alt_dma_rxchan rxchan;
  int rc;
  int offset;
  int counta,countb;
  int temp_x =0,temp_y =0;
  void* data_written_1;
  void* data_read_1;
  void* data_written_2;
  void* data_read_2;
  data_written_2 = (void*)&data_frame_2;
  data_read_2 = (void*)&temp_frame_2;
  if (x == 0)
    temp_x = 12;//adjusting pointer to the right position for writing
  else
    x -= 12;
  if (y == 0 )
    temp_y = 12;
  else
    y -= 12;
  data_written_1 = (void*)&data_frame_1;
  data_read_1 = (void*)&temp_frame_1;
  counta = x+y*320;//data_written_1_count
  countb = temp_x+temp_y*40;//data_read_1_count
  
  // Create the transmit channel //
  if ((txchan = alt_dma_txchan_open("/dev/dma")) == NULL)
  {
    printf ("Failed to open transmit channel\n");
    exit (1);
  }  
  // Create the receive channel 
  if ((rxchan = alt_dma_rxchan_open("/dev/dma")) == NULL)
  {
    printf ("Failed to open receive channel\n");
    exit (1);
  }
  for (;counta< Y_SIZE*X_SIZE&&countb < 1600; data_written_1+=320, data_read_1+=40, counta+=320,countb+=40){
    /// Use DMA to transfer from write buffer to memory under test /
   //  Post the transmit request /
    if ((rc = alt_dma_txchan_send (txchan, data_written_1, 0x28, NULL, NULL)) < 0)
    {
      printf ("Failed to post transmit request, reason = %i\n", rc);
      exit (1);
    }
    // Post the receive request /
    if ((rc = alt_dma_rxchan_prepare (rxchan, data_read_1, 0x28, dma_done, NULL)) < 0)
    {
      printf ("Failed to post read request, reason = %i\n", rc);
      exit (1);
    }
  }  
  /// Wait for transfer to complete //
  while (!rx_done);
  rx_done = 0;
  for (offset = 0; offset< 16; offset++,data_read_2+=16,data_written_2+=320){
    if ((rc = alt_dma_txchan_send (txchan, data_written_2, 0x10, NULL, NULL)) < 0)
    {
      printf ("Failed to post transmit request, reason = %i\n", rc);
      exit (1);
    }
    // Post the receive request //
    if ((rc = alt_dma_rxchan_prepare (rxchan, data_read_2, 0x10, dma_done, NULL)) < 0)
    {
      printf ("Failed to post read request, reason = %i\n", rc);
      exit (1);
    }
  }
  while (!rx_done);
  rx_done = 0;
  alt_dma_txchan_close (txchan);
  alt_dma_rxchan_close (rxchan);
}
No RepliesBe the first to reply