赞
踩
/* * 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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。