cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
mrelko
Adventurer
Adventurer
6,029 Views
Registered: ‎05-10-2013

How to send/recieve data to FIR continuously? [SDK Help] [Zynq]

I have an FIR filter implemented in fabric with an AXIStream interface. I believe these parts of the design are correct. The problem I am having is pushing the data to the fabric FIR. For the Zynq it needs to go through a DMA to allow the AXIStream to work if I am not mistaken. I am using the following to test that data is being sent, however when I use the vivado waveform analysis tool, I do not see the data come through to the DMA. I followed the Vivado HLS Tutorial for streaming arrays to generate the following code, which apparently is wrong. Can someone help?

int inputData = 3, outputData = 5;
Xil_DCacheFlushRange((unsigned) inputData, sizeof(int));
Xil_DCacheFlushRange((unsigned) outputData, sizeof(int));
XAxiDma_SimpleTransfer(&axiDma, (int) inputData, sizeof(int), XAXIDMA_DMA_TO_DEVICE);

while(inputData<50){
inputData=inputData+1;
XAxiDma_SimpleTransfer(&axiDma, (int) inputData, sizeof(int), XAXIDMA_DMA_TO_DEVICE);
//XAxiDma_SimpleTransfer(&axiDma, (int) outputData, sizeof(int), XAXIDMA_DEVICE_TO_DMA);
printf("Out: %d \n\r", outputData);
}

0 Kudos
13 Replies
bwiec
Xilinx Employee
Xilinx Employee
6,018 Views
Registered: ‎08-02-2011

I would recommend referring to this code for the DMA
C:\Xilinx\SDK\2013.2\sw\XilinxProcessorIPLib\drivers\axidma_v7_02_a\examples\xaxidma_example_simple_poll.c

 

Also, make sure to drive tkeep and tlast correctly.

www.xilinx.com
0 Kudos
mrelko
Adventurer
Adventurer
6,011 Views
Registered: ‎05-10-2013

For a continuous stream of data coming in, what would I want to do for Tlast?  See the attacked picture for what I have currently driven.  

 

Also, this is my HLS function.  one int in, one int out using an AXIStream..  
void FIFOfir(volatile uint10 * x, volatile uint10 * y)

 

 

Capture.PNG
0 Kudos
bwiec
Xilinx Employee
Xilinx Employee
5,993 Views
Registered: ‎08-02-2011

You should drive it appropriately depending on how you are setting the length register in the DMA. It should be asserted for the last beat of the packet.
www.xilinx.com
0 Kudos
houssem1992
Observer
Observer
4,039 Views
Registered: ‎06-28-2015

hi all ,

 

I have the same problem . i want to give my input this input Data  : double eingang[5] = {1,5,6,3,2};

 

i receive from the beginning :

                                                           Entering main()

                                                         XAxiDma_SimplePollExample: Failed\r\n

 

 

can someone help me to corecct the code in SDK .  this is the code on sdk from the simple dma example and modified .

 

#include <stdio.h>
#include "platform.h"
#include "xaxidma.h"
#include "xparameters.h"

/*
 * Device hardware build related constants.
 */

#define DMA_DEV_ID		XPAR_AXIDMA_0_DEVICE_ID

//#define MEM_BASE_ADDR		(XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x1000000)
#define MEM_BASE_ADDR		(XPAR_PS7_DDR_0_S_AXI_BASEADDR + 0x10000000)

#define TX_BUFFER_BASE		(MEM_BASE_ADDR + 0x00100000)
#define RX_BUFFER_BASE		(MEM_BASE_ADDR + 0x00300000)
#define RX_BUFFER_HIGH		(MEM_BASE_ADDR + 0x004FFFFF)

#define MAX_PKT_LEN        5

#define TEST_START_VALUE    0xC


/************************** Function Prototypes ******************************/

int XAxiDma_SimplePollExample(u16 DeviceId);

/************************** Variable Definitions *****************************/
/*
 * Device instance definitions
 */
XAxiDma AxiDma;


double eingang[5] = {1,5,6,3,2};


int main()
{
	int Status;

    init_platform();
	xil_printf("\r\n--- Entering main() --- \r\n");

	/* Run the poll example for simple transfer */
	Status = XAxiDma_SimplePollExample(DMA_DEV_ID);

	if (Status != XST_SUCCESS) {

		xil_printf("XAxiDma_SimplePollExample: Failed\r\n");
		return XST_FAILURE;
	}

	xil_printf("XAxiDma_SimplePollExample: Passed\r\n");

	xil_printf("--- Exiting main() --- \r\n");

	return XST_SUCCESS;

}



int XAxiDma_SimplePollExample(u16 DeviceId)
{

    XAxiDma_Config *CfgPtr;
    int Status;
    int Index;
    float *TxBufferPtr;
    float *RxBufferPtr;
    float Value;
    u32 *ptr = (u32*)0x40400000;
    int i;
    TxBufferPtr = (float *)TX_BUFFER_BASE ;
    RxBufferPtr = (float *)RX_BUFFER_BASE;


    /* Initialize the XAxiDma device.
         */
        CfgPtr = XAxiDma_LookupConfig(DeviceId);
        if (!CfgPtr) {
            xil_printf("No config found for %d\r\n", DeviceId);
            return XST_FAILURE;
        }


        if(XAxiDma_HasSg(&AxiDma)){
               xil_printf("Device configured as SG mode \r\n");
               return XST_FAILURE;
           }

    /* Disable interrupts, we use polling mode
    */
     XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
              XAXIDMA_DEVICE_TO_DMA);
     XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
              XAXIDMA_DMA_TO_DEVICE);



     Value = TEST_START_VALUE;

         for(Index = 0; Index < MAX_PKT_LEN; Index ++) {
             TxBufferPtr[Index] = Value;

             Value =eingang[Index];
         }
         /* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
          * is enabled
          */
         Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN);



         if (Status != XST_SUCCESS) {
                   return XST_FAILURE;
               }

               Status = XAxiDma_SimpleTransfer(&AxiDma, (u32)TxBufferPtr,
                       MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);

               if (Status != XST_SUCCESS) {
                   return XST_FAILURE;
               }


         Status = XAxiDma_SimpleTransfer(&AxiDma, (u32)RxBufferPtr,
                 MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);



         for (i=0; i<5; i++) {
                 printf("0x%08x = %x\r\n", ptr+i, *(ptr+i));
             }
             printf("\r\n");


         while ((XAxiDma_Busy(&AxiDma,XAXIDMA_DEVICE_TO_DMA)) ||
                 (XAxiDma_Busy(&AxiDma,XAXIDMA_DMA_TO_DEVICE))) {
             /* Wait */
         }

         return XST_SUCCESS;
     }

thank you

houssem

 

0 Kudos
houssem1992
Observer
Observer
4,017 Views
Registered: ‎06-28-2015

Hi bwies

can you help me please .

 

I see your posts about dma controller and i want to implement my fir filter in Zedboard .

 

0 Kudos
houssem1992
Observer
Observer
4,013 Views
Registered: ‎06-28-2015

Hi bwies

can you help me please .

 

I see your posts about dma controller and i want to implement my fir filter in Zedboard .

 i try now with another c-code to test the design . i call the ( source- , receiver- , control- ..)register of dma . I set in the memory location (MM2S)  to 1 and i want to read the output ( S2MM) . can you help me to correct this code or tell me where is the problem ? i still in this part since one week . this is my code :

//  #include <stdio.h>            // disable when program itself directly controls UART  ....  (thus no xil_printf anymore ...)
#include "platform.h"
#include "xparameters.h"
//#include "xbasic_types.h"
#include "xil_types.h"
#include "xil_io.h"
#include "xil_exception.h"
#include "xscugic.h"








//Macros
#define CHECK_BIT(var,pos) ((var & (1<<pos)))




//The DMA registers Direct Register Mode
#define DMA_BASE_ADDR 0x40400000

volatile u32 *MM2S_DMACR   	= (u32 *) (DMA_BASE_ADDR+ 0x00) ; //MM2S DMA Control register
volatile u32 *MM2S_DMASR   	= (u32 *) (DMA_BASE_ADDR+ 0x04) ; //MM2S DMA Status register
volatile u32 *MM2S_SA    	= (u32 *) (DMA_BASE_ADDR+ 0x18) ; //MM2S Source Address
volatile u32 *MM2S_LENGTH  	= (u32 *) (DMA_BASE_ADDR+ 0x28) ; //MM2S Transfer Length (Bytes)
volatile u32 *S2MM_DMACR   	= (u32 *) (DMA_BASE_ADDR+ 0x30) ; //S2MM DMA Control register
volatile u32 *S2MM_DMASR   	= (u32 *) (DMA_BASE_ADDR+ 0x34) ; //S2MM DMA Status register
volatile u32 *S2MM_DA    	= (u32 *) (DMA_BASE_ADDR+ 0x48) ; //S2MM Destination Address
volatile u32 *S2MM_LENGTH  	= (u32 *) (DMA_BASE_ADDR+ 0x58) ; //S2MM Buffer Length (Bytes)









//functions
void init_DMA_direct(); //initialise the DMA in direct mode
void start_DMA_direct(); //starts the DMA in direct mode
void set_memory(u32 addr, u32 length, u32 value); //sets a certain value into a memory range
void print_memory(u32 addr, u32 length); //prints the value of a memory range
void MM2S_ISR();
void S2MM_ISR();


void init_DMA_direct(){
	*MM2S_DMACR = 0x00000001; //enable the MM2S DMA
	*S2MM_DMACR = 0x00000001; //enable the S2MM DMA
	xil_printf("MM2S status is = %x S2MM status = %x\n\r",*MM2S_DMASR,*S2MM_DMASR); // print for debug purpose
}



void start_DMA_direct(){
	*MM2S_SA = 0x00100000; //setting the MM2S source addr
	*S2MM_DA = 0x00200000;	//setting the S2MM source addr
	set_memory(0x00100000, 4,0x000000001); //set the MM2S memory locations to one

	*MM2S_LENGTH = (4*4); // set the length of the MM2S and starts the MM2S

}


void set_memory(u32 addr, u32 length, u32 value){
	int i;
	u32 *ptr = (u32 *) addr;
	for(i = 0; i < length; i++){
		*ptr = value;
		ptr++;
	}
}


void print_memory(u32 addr, u32 length){
	int i;
	u32 *ptr = (u32 *)addr;
	for(i = 0; i < length; i++){
		xil_printf("memory addr = %x with value = %x \n\r", ptr, *ptr);
		ptr++;
	}
}


void MM2S_ISR(){

}


void S2MM_ISR(){

}








int main()
{
    init_platform();

    init_DMA_direct(); //initialise the DMA in direct mode
    start_DMA_direct(); //starts the DMA in direct mode


    print_memory(0x00100000,4);

    print_memory( 0x00200000,4);

    xil_printf("Hello World\n\r");

    return 0;
}


my result :

Unbenannt.png

 

the design :

2.png

 

 

it will be so great when you help me .

 

thanks

houssem

0 Kudos
bwiec
Xilinx Employee
Xilinx Employee
3,956 Views
Registered: ‎08-02-2011

Hi Houssem,

Did you flush your cache before reading back those memory locations? I don't see it.
www.xilinx.com
0 Kudos
houssem1992
Observer
Observer
3,938 Views
Registered: ‎06-28-2015

Hi bwies ,

 

 

thank you for the reply . my code is from the eample  code of xilnix . http://forums.xilinx.com/xlnx/attachments/xlnx/NewUser/16910/1/helloworld.c

 

in the main , i write in the memory the value 2 for all memory location  with set_memory  function .

i want to transfer this data with start_DMA_direct() .

void start_DMA_direct(){
	*MM2S_SA = 0x00100000; //setting the MM2S source addr
	*S2MM_DA = 0x00200000;	//setting the S2MM source addr
	set_memory(0x00100000, 4,0x000000001); //set the MM2S memory locations to one
	set_memory(0x00200000, 4,0x000000000); //set the MM2S memory locations to one



	*MM2S_LENGTH = (4*4); // set the length of the MM2S and starts the MM2S
	*S2MM_LENGTH = (4*4); // set the length of the S2MM and starts the S2MM

}

 i flush the memory locations of MM2S and S2MM.

i receive now the inzialized value of the function start_DMA_direct().

 

i think that the transfer of the data  to my fir-filter is not happned . ?

 

int main()
{
    init_platform();

    init_DMA_direct(); //initialise the DMA in direct mode


    Xil_DCacheFlushRange(0x00100000, 4);
    Xil_DCacheFlushRange(0x00200000, 4);

    set_memory(0x00100000, 4,0x000000002); //set the MM2S memory locations to 2

    start_DMA_direct(); //starts the DMA in direct mode


    print_memory(0x00100000,4);



    print_memory(0x00200000,4);


    xil_printf("Hello World\n\r");

    return 0;
}

 

thanks

houssem

 

0 Kudos
houssem1992
Observer
Observer
3,937 Views
Registered: ‎06-28-2015

i receive this result now :

 

no Transfer is happened i think ?

3.png

0 Kudos
bwiec
Xilinx Employee
Xilinx Employee
2,351 Views
Registered: ‎08-02-2011

Hello,

 

You said

 

	*MM2S_LENGTH = (4*4); // set the length of the MM2S and starts the MM2S
	*S2MM_LENGTH = (4*4); // set the length of the S2MM and starts the S2MM

So that's only 4 words to be transferred. Which is what it looks like in your terminal message, right?

www.xilinx.com
0 Kudos
houssem1992
Observer
Observer
2,334 Views
Registered: ‎06-28-2015

hi bwiec,

 

thank you for reply . i follow the programming sequence of the datasheet of the dma (Page 72 ). http://www.xilinx.com/support/documentation/ip_documentation/axi_dma/v7_1/pg021_axi_dma.pdf

 

for example for MM2S Sequence : 

1)Start the MM2S channel running by setting run/stop bit to 1 (MM2S_DMACR.RS = 1
 2)write a valid source address to the MM2S_SA register
3)write the number of bytes to transfer in the MM2S_LENGTH register.A non-zero value causes the MM2S_LENGTH number of bytes to be read on the MM2S AXI4 interface and transmitted out of the MM2S AXI4-Stream interface. The MM2S_LENGTH register must be written last.
that what i find . sorry if i'm ignorant. If you have an example (c-code or  tutorial (i use windows 7 ) ) for the using of DMA which can help me . that will be greatly appreciated .

 

thanks

houssem

 

0 Kudos
bwiec
Xilinx Employee
Xilinx Employee
2,244 Views
Registered: ‎08-02-2011

Hi Houssem,

 

I don't follow you. It seems like the behavior is correct and you confirmed it. What is still unclear?

 

I do have some examples:

 

www.xilinx.com
houssem1992
Observer
Observer
2,235 Views
Registered: ‎06-28-2015

hi all ,

 

 

i try now to test the design with the simple dma example c.code  from xilinx . my software on the ARM is never getting out of this part of the programm !

 

if(XAxiDma_HasSg(&AxiDma)){
            xil_printf("Device configured as SG mode \r\n");
            return XST_FAILURE;
        }

in my design i don t use the scatter gather mode . is that  a problem in the Hardware  part ?

this is a part of  the vhdl code of my simple filter :

    -- this is the process in  fir10_v1_0_S_AXIS.vhd  
    -- X receive the input data from s_axis_tdata


signal a,b,c :std_logic_vector(C_M_AXIS_TDATA_WIDTH-1 downto 0):=(others => '0');
                signal y :std_logic_vector(34 downto 0 ):= (others => '0');
                signal k1:std_logic_vector(2 downto 0):="011";
                signal k2:std_logic_vector(2 downto 0):="010";
            -- Add user logic here
    begin
    -- User logic ends
                                                                    
    
        -- Add user logic here
      
          process(X,M_AXIS_ACLK) 
          
          begin
          if (M_AXIS_ACLK='1') and (M_AXIS_ACLK'event) 
          then
                  -- Verzögerung von Inputsignale bei jedem clockTakt 
                      c<=b;
                      b<=a;
                      a<=X;
                      y<=(k1*a + k2*c);  -- Ausgangs Signal 
                      M_AXIS_TDATA<=y(31 downto 0 ); -- Ausgangs auf die 32 Bits begrenzen 
          
                      
           end if ;           
                      
          
          end process ; 

 

this is the c code (  without my fir block the code is working without error and the memory is copied from the transmitter to the receiver )

 

/* Initialize the XAxiDma device.
	 */
	CfgPtr = XAxiDma_LookupConfig(DeviceId);
	if (!CfgPtr) {
		xil_printf("No config found for %d\r\n", DeviceId);
		return XST_FAILURE;
	}

	Status = XAxiDma_CfgInitialize(&AxiDma, CfgPtr);
	if (Status != XST_SUCCESS) {
		xil_printf("Initialization failed %d\r\n", Status);
		return XST_FAILURE;
	}

	if(XAxiDma_HasSg(&AxiDma)){
			xil_printf("Device configured as SG mode \r\n");
			return XST_FAILURE;
		}

	/* Disable interrupts, we use polling mode
	 */
	XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
						XAXIDMA_DEVICE_TO_DMA);
	XAxiDma_IntrDisable(&AxiDma, XAXIDMA_IRQ_ALL_MASK,
						XAXIDMA_DMA_TO_DEVICE);

	Value = 0;


	// TxBufferPtr[8] = {0,1,2,3,4,5,6,7 }

	for(Index = 0; Index < MAX_PKT_LEN_WORDS; Index ++) {
			TxBufferPtr[Index] = Value;
			Value++;
	}
	/* Flush the SrcBuffer before the DMA transfer, in case the Data Cache
	 * is enabled
	 */
	Xil_DCacheFlushRange((u32)TxBufferPtr, MAX_PKT_LEN);



// device to DMA Transfer
		Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) RxBufferPtr,
					MAX_PKT_LEN, XAXIDMA_DEVICE_TO_DMA);

		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}


// DMA to Device Transfer

		Status = XAxiDma_SimpleTransfer(&AxiDma,(u32) TxBufferPtr,
					MAX_PKT_LEN, XAXIDMA_DMA_TO_DEVICE);


		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}




		while (XAxiDma_Busy(&AxiDma,XAXIDMA_DMA_TO_DEVICE)) {
				/* Wait */
		}
		while (XAxiDma_Busy(&AxiDma,XAXIDMA_DEVICE_TO_DMA)) {
				/* Wait */
		}

		Status = CheckData();
		if (Status != XST_SUCCESS) {
			return XST_FAILURE;
		}

 

please help

 

thanks

houssem

 

0 Kudos