xilinx提供测试dma和fft在sdk端的代码
Posted 只是有点小怂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了xilinx提供测试dma和fft在sdk端的代码相关的知识,希望对你有一定的参考价值。
- 来自ug871的ch10 Using HLS IP in a Zynq SoC Design的lab2 Streaming Data Between the Zynq CPU and HLS Accelerator Blocks
/*
* Copyright (c) 2009-2012 Xilinx, Inc. All rights reserved.
*
* Xilinx, Inc.
* XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
* COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
* ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
* STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
* IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
* FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
* XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
* THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
* ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
* FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE.
*
*/
/*
* helloworld.c: simple test application
*
* This application configures UART 16550 to baud rate 9600.
* PS7 UART (Zynq) is not initialized by this application, since
* bootrom/bsp configures it to baud rate 115200
*
* ------------------------------------------------
* | UART TYPE BAUD RATE |
* ------------------------------------------------
* uartns550 9600
* uartlite Configurable only in HW design
* ps7_uart 115200 (configured by bootrom/bsp)
*/
#include <stdio.h>
#include "platform.h"
#if 0 // The original 'Hello World' code
void print(char *str);
int main()
{
init_platform();
print("Hello World\\n\\r");
return 0;
}
#else
#include <stdlib.h> // Std C functions, e.g. exit()
#include <math.h> // libm header: sqrt(), cos(), etc
#include "xparameters.h" // System parameter definitions
#include "xaxidma.h" // Device driver API for AXI DMA
// Define the length of the (real input) FFT data
#define REAL_FFT_LEN 1024
// Define a type to hold complex FFT output (real) spectral data
typedef struct {
short re;
short im;
} complex16;
// Helper function forward declarations
int init_dma(XAxiDma *axiDma);
void generate_waveform(short *signal_buf, int num_samples);
// Program entry point
int main()
{
// Declare a XAxiDma object instance
XAxiDma axiDma;
// Local variables
int i, j;
int status;
static short realdata[4*REAL_FFT_LEN];
volatile static complex16 realspectrum[REAL_FFT_LEN/2];
// Initialize the platform
init_platform();
print("---------------------------------------\\n\\r");
print("- RealFFT PL accelerator test program -\\n\\r");
print("---------------------------------------\\n\\r");
// Initialize the (simple) DMA engine
status = init_dma(&axiDma);
if (status != XST_SUCCESS) {
exit(-1);
}
// Generate a waveform to be input to FFT
for (i = 0; i < 4; i++)
generate_waveform(realdata + i * REAL_FFT_LEN, REAL_FFT_LEN);
// *IMPORTANT* - flush contents of 'realdata' from data cache to memory
// before DMA. Otherwise DMA is likely to get stale or uninitialized data
Xil_DCacheFlushRange((unsigned)realdata, 4 * REAL_FFT_LEN * sizeof(short));
// DMA enough data to push out first result data set completely
status = XAxiDma_SimpleTransfer(&axiDma, (u32)realdata,
4 * REAL_FFT_LEN * sizeof(short), XAXIDMA_DMA_TO_DEVICE);
status = XAxiDma_SimpleTransfer(&axiDma, (u32)realdata,
4 * REAL_FFT_LEN * sizeof(short), XAXIDMA_DMA_TO_DEVICE);
// Do multiple DMA xfers from the RealFFT core's output stream and
// display data for bins with significant energy. After the first frame,
// there should only be energy in bins around the frequencies specified
// in the generate_waveform() function - currently bins 191~193 only
for (i = 0; i < 8; i++) {
// Setup DMA from PL to PS memory using AXI DMA's 'simple' transfer mode
status = XAxiDma_SimpleTransfer(&axiDma, (u32)realspectrum,
REAL_FFT_LEN / 2 * sizeof(complex16), XAXIDMA_DEVICE_TO_DMA);
// Poll the AXI DMA core
do {
status = XAxiDma_Busy(&axiDma, XAXIDMA_DEVICE_TO_DMA);
} while(status);
// Data cache must be invalidated for 'realspectrum' buffer after DMA
Xil_DCacheInvalidateRange((unsigned)realspectrum,
REAL_FFT_LEN / 2 * sizeof(complex16));
// DMA another frame of data to PL
if (!XAxiDma_Busy(&axiDma, XAXIDMA_DMA_TO_DEVICE))
status = XAxiDma_SimpleTransfer(&axiDma, (u32)realdata,
REAL_FFT_LEN * sizeof(short), XAXIDMA_DMA_TO_DEVICE);
printf("\\n\\rFrame #%d received:\\n\\r", i);
// Detect energy in spectral data above a set threshold
for (j = 0; j < REAL_FFT_LEN / 2; j++) {
// Convert the fixed point (s.15) values into floating point values
float real = (float)realspectrum[j].re / 32767.0f;
float imag = (float)realspectrum[j].im / 32767.0f;
float mag = sqrtf(real * real + imag * imag);
if (mag > 0.00390625f) {
printf("Energy detected in bin %3d - ",j);
printf("{%8.5f, %8.5f}; mag = %8.5f\\n\\r", real, imag, mag);
}
}
printf("End of frame.\\n\\r");
fflush(stdout);
}
printf("***************\\n\\r");
printf("* End of test *\\n\\r");
printf("***************\\n\\r\\n\\r");
return 0;
}
// A function that generates a waveform with a period of 'num_samples'
void generate_waveform(short *signal_buf, int num_samples)
{
const float cycles_per_win = 192.0f;
const float phase = 0.0f;
const float ampl = 0.9f;
int i;
for (i = 0; i < num_samples; i++) {
float sample = ampl *
cosf((i * 2 * M_PI * cycles_per_win / (float)num_samples) + phase);
signal_buf[i] = (short)(32767.0f * sample);
}
}
// A function that wraps all AXI DMA initialization related API calls
int init_dma(XAxiDma *axiDmaPtr){
XAxiDma_Config *CfgPtr;
int status;
// Get pointer to DMA configuration
CfgPtr = XAxiDma_LookupConfig(XPAR_AXIDMA_0_DEVICE_ID);
if(!CfgPtr){
print("Error looking for AXI DMA config\\n\\r");
return XST_FAILURE;
}
// Initialize the DMA handle
status = XAxiDma_CfgInitialize(axiDmaPtr,CfgPtr);
if(status != XST_SUCCESS){
print("Error initializing DMA\\n\\r");
return XST_FAILURE;
}
//check for scatter gather mode - this example must have simple mode only
if(XAxiDma_HasSg(axiDmaPtr)){
print("Error DMA configured in SG mode\\n\\r");
return XST_FAILURE;
}
//disable the interrupts
XAxiDma_IntrDisable(axiDmaPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DEVICE_TO_DMA);
XAxiDma_IntrDisable(axiDmaPtr, XAXIDMA_IRQ_ALL_MASK,XAXIDMA_DMA_TO_DEVICE);
return XST_SUCCESS;
}
#endif
以上是关于xilinx提供测试dma和fft在sdk端的代码的主要内容,如果未能解决你的问题,请参考以下文章