Descriptor Examples

The following code shows the descriptor structure example in C language.

struct dmasg_descriptor {
// See all DMASG_DESCRIPTOR_STATUS_* defines
// Updated by the DMA at the end of each descriptor and when a S -> M packet is completely transferred into memory
u32 status;
// See all DMASG_DESCRIPTOR_CONTROL_* defines
u32 control;
// For M -> ? transfers, memory address of the input data
u64 from;
// For ? -> M transfers, memory address of the output data
u64 to;
// Memory address of the next descriptor
u64 next;
}
You need to define the descriptor to either write to memory or read from memory. Depending on whether it is a read or write operation:
  • Memory to AXI4-Stream—The from register stores the target address of the memory, and the to should be 0.
  • AXI4-Stream to Memory—The to register stores the target address of the memory, and the from should be 0.
The control register stores the number of bytes to be accessed.

The following descriptor examples show the linked-list operations:

Note: The dmasg_input_memory, dmasg_output_memory, dmasg_input_stream, are dmasg_linked_list_start functions that are defined in the driver (dmasg.h) file of the SoC SDK.

Memory to AXI4-Stream Descriptor Example

volatile struct dmasg_descriptor descriptors1[FRAME_RATE+1]  __attribute__ ((aligned (64)));
   for (int j=0; j<FRAME_RATE+1; j=j+1 ) {
      if(j == FRAME_RATE){
         descriptors1[j].status  = DMASG_DESCRIPTOR_STATUS_COMPLETED;
      } else {
         descriptors1[j].control = (u32)((BUFFER_SIZE)-1)  | 1 << 30;;
         descriptors1[j].from    = (u32)(sb32 + (j *(BUFFER_SIZE)));
         descriptors1[j].to      = 0;
         descriptors1[j].next    = (u32) (descriptors1 + (j+1));
         descriptors1[j].status  = 0; 
         }
      }
   dmasg_input_memory (DMASG_BASE, ST32_OUT,  sb32, 16);
   dmasg_output_stream(DMASG_BASE, ST32_OUT, 0, 0, 0, 1);
   dmasg_linked_list_start(DMASG_BASE, ST32_OUT, (u32) descriptors1);

AXI4-Stream to Memory Descriptor Example

volatile struct dmasg_descriptor descriptors0[FRAME_RATE+1]  __attribute__ ((aligned (64)));
   for (int j=0; j<FRAME_RATE+1; j=j+1 ) {
      if(j == FRAME_RATE){
         descriptors0[j].status  = DMASG_DESCRIPTOR_STATUS_COMPLETED;
      } else {
         descriptors0[j].control = (u32)((BUFFER_SIZE)-1)  | 1 << 30;;
         descriptors0[j].from    = 0;
         descriptors0[j].to      = (u32)(db32 + (j *(BUFFER_SIZE)) );
         descriptors0[j].next    = (u32) (descriptors0 + (j+1));
         descriptors0[j].status  = 0;
      }
   }
   dmasg_output_memory (DMASG_BASE, ST32_IN,  db32, 16);
   dmasg_input_stream(DMASG_BASE, ST32_IN, 0, 1, 0);
   dmasg_linked_list_start(DMASG_BASE, ST32_IN, (u32) descriptors0);

Memory to Memory Descriptor Example

volatile struct dmasg_descriptor descriptors2[FRAME_RATE+1]  __attribute__ ((aligned (64)));
   for (int j=0; j<FRAME_RATE+1; j=j+1 ) {
      if(j == FRAME_RATE) {
         descriptors2[j].status  = DMASG_DESCRIPTOR_STATUS_COMPLETED;
      } else {
         descriptors2[j].control = (u32)((BUFFER_SIZE)-1)  | 1 << 30;;
         descriptors2[j].from    = (u32)(sb32 + (j *(BUFFER_SIZE)));
         descriptors2[j].to      = (u32)(db32 + (j *(BUFFER_SIZE)) );
         descriptors2[j].next    = (u32) (descriptors2 + (j+1));
         descriptors2[j].status  = 0;
      }
   }
   dmasg_input_memory  ( DMASG_BASE, ST32_M2M,  sb32, 16);
   dmasg_output_memory (DMASG_BASE, ST32_M2M,  db32, 16);
   dmasg_linked_list_start(DMASG_BASE, ST32_M2M, (u32) descriptors2);