📄 testapp_memorycaching.c
字号:
/**************************************************************************** XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"* SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR* XILINX DEVICES. 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.** (c) Copyright 2006 Xilinx, Inc.* All rights reserved.***************************************************************************//*************************************************************************** Filename: TestApp_MemoryCaching.c** Description:* This software application tests the caching ability of PLB DDR2* with OPB Central DMA. The software application is executed from the cacheable* region of memory, while DMA transactions are occurring inside the non-cacheable* region of memory. The memory region assigned to source address gets copied
* to the memory region assigned to the destination address. When this operation
* is finished, it causes an interrupt that should be cleared by the software application
* and the memory region assigned to the destination data is checked against* the source data to ensure proper transfer. The LEDs light up once the* transaction is successful.*** MODIFICATION HISTORY:** Ver Who Date Changes* ----- ---- -------- -------------------------------------------------------* 1.00 jel 7-29-05 Initial Release* 2.00 jel 6-27-06 Modified interrupts and caching for PPC405.* Modified GPIO function.*********************************************************************************//***************************** Include Files *********************************/#include "xparameters.h"#include "xutil.h"#include "xdmacentral.h"#include "xintc.h"#include "xgpio.h"#include "xcache_l.h"#include "xexception_l.h"/************************** Constant Definitions *****************************/#define OPB_CENTRAL_DMA_BASEADDR XPAR_OPB_CENTRAL_DMA_0_BASEADDR // OPB Central DMA Base Address#define OPB_CENTRAL_DMA_CR 0xC0000004 // Set SINC, DINC, and word size operations#define OPB_CENTRAL_DMA_SA XPAR_DDR2_SDRAM_32MX64_MEM0_BASEADDR + 0x8101000 // Source Address for DMA#define OPB_CENTRAL_DMA_DA XPAR_DDR2_SDRAM_32MX64_MEM0_BASEADDR + 0x8202000 // Destination Address for DMA#define OPB_CENTRAL_DMA_LEN BUFFER_BYTESIZE // Length of DMA operation#define INTC_DEVICE_ID XPAR_OPB_INTC_0_DEVICE_ID#define INTR_ID XPAR_OPB_INTC_0_OPB_CENTRAL_DMA_0_DMA_INTERRUPT_INTR#define BUFFER_BYTESIZE 1048576#define BUFFER_WORDSIZE \ ((BUFFER_BYTESIZE + sizeof(Xuint32) - 1) / sizeof(Xuint32))/************************** Function Prototypes ******************************/void error(void);static void SrcDesWriteClear(XIo_Address SrcA, XIo_Address DesA);static XStatus WaitForComp();void GpioOutputExample(Xuint16 DeviceId, Xuint32 GpioWidth);static void DmaInterruptHandler(void *CallBackRef);static XStatus SetupInterruptSystem(XDmaCentral *DmaCentralPtr);/************************** Variable Defintions ******************************//* Create instances for the Interrupt and Central DMA */static XDmaCentral DmaCentral;static XIntc InterruptController;/* Instance For GPIO */XGpio GpioOutput;/* * Shared variables used to test the callbacks. */volatile static Xboolean DmaDone = XFALSE; /* Dma transfer is done */volatile static Xboolean DmaBusError = XFALSE; /* Dma Bus Error occurs */volatile static Xboolean DmaBusTimeout = XFALSE; /* Dma Bus Timeout occurs *///====================================================int main (void) {
/* DMA device ID */ Xuint16 DeviceId = XPAR_OPB_CENTRAL_DMA_0_DEVICE_ID; XStatus Status;
/* Designate memory locations for the Source and Destination addresses */ XIo_Address SourceAdd; XIo_Address DesAdd; SourceAdd = OPB_CENTRAL_DMA_SA; DesAdd = OPB_CENTRAL_DMA_DA;
/* * Enable and initialize cache within 128MB from 0x00000000 */ XCache_EnableICache(0x80000000); XCache_EnableDCache(0x80000000); xil_printf("-- Entering main() --\r\n");
/* Write and clear source and destination addresses */ SrcDesWriteClear(SourceAdd, DesAdd); /* Initialize the dma instance */ Status = XDmaCentral_Initialize(&DmaCentral,DeviceId); if (Status != XST_SUCCESS) { xil_printf("The Central DMA Didn't Initialize! \r\n"); error(); } /* Reset the DMA device. */ (void)XDmaCentral_Reset(&DmaCentral); /* Setup the DMA Control register to be: * - source address incrementing * - destination address incrementing * - using word data size */ XDmaCentral_SetControl(&DmaCentral, OPB_CENTRAL_DMA_CR); /* Enable DMA Done and DMA Error interrupts */ XDmaCentral_InterruptEnableSet(&DmaCentral, XDMC_IXR_DMA_DONE_MASK | XDMC_IXR_DMA_ERROR_MASK); /* Setup interrupt system */ Status = SetupInterruptSystem(&DmaCentral); if (Status != XST_SUCCESS) { xil_printf("The Interrupt System Didn't Initialize! \r\n"); error(); } /* Start the DMA transfer. */ xil_printf("\r\nStarting DMA Transfer\r\n"); XDmaCentral_Transfer(&DmaCentral, (void *)OPB_CENTRAL_DMA_SA, (void *)OPB_CENTRAL_DMA_DA, BUFFER_BYTESIZE); /* Wait until the DMA transfer is done or Bus error/timeout occurs. */ Status = WaitForComp(); if (Status != XST_SUCCESS) { xil_printf("DMA Transactions Were Not Successful \r\n"); error(); } xil_printf("\r\nCongratulations! DMA Operations Completed Successfully!\r\n"); /* Let the LEDs blink if everything worked correctly */ GpioOutputExample(XPAR_LEDS_8BIT_DEVICE_ID,8); xil_printf("\r\n-- Exiting main() --\r\n"); return 0;}static XStatus SetupInterruptSystem(XDmaCentral *DmaCentralPtr){ XStatus Result; /* * Initialize the interrupt controller driver so that it's ready to use. */ Result = XIntc_Initialize(&InterruptController, INTC_DEVICE_ID); if (Result != XST_SUCCESS) { return Result; } /* * Connect the device driver handler that will be called when an interrupt * for the device occurs, the handler defined above performs the specific * interrupt processing for the device */ Result = XIntc_Connect(&InterruptController, INTR_ID, (XInterruptHandler)DmaInterruptHandler, DmaCentralPtr); if (Result != XST_SUCCESS) { return Result; } /* * Start the interrupt controller so interrupts are enabled for all * devices that cause interrupts. Specify real mode so that the DMA device * can cause interrupts through the interrupt controller. */ Result = XIntc_Start(&InterruptController, XIN_REAL_MODE); if (Result != XST_SUCCESS) { return Result; } /* Enable the interrupt for the DMA device */ XIntc_Enable(&InterruptController, INTR_ID); /* * Initialize the PPC405 exception table */ XExc_Init(); /* * Register the interrupt controller handler with the exception table */ XExc_RegisterHandler(XEXC_ID_NON_CRITICAL_INT, (XExceptionHandler)XIntc_InterruptHandler, &InterruptController); /* * Enable non-critical exceptions */ XExc_mEnableExceptions(XEXC_NON_CRITICAL); return XST_SUCCESS;}static void DmaInterruptHandler(void *CallBackRef){ Xuint32 IntrStatusValue; Xuint32 StatusValue; XDmaCentral *DmaCentralPtr = (XDmaCentral *)CallBackRef; /* * Get the interrupt status from the device and check the value. */ IntrStatusValue = XDmaCentral_InterruptStatusGet(DmaCentralPtr); if (IntrStatusValue & XDMC_IXR_DMA_ERROR_MASK) /* DMA Error Interrupt */ { /* Read DMA Status register. */ StatusValue = XDmaCentral_GetStatus(DmaCentralPtr); if (StatusValue & XDMC_DMASR_BUS_ERROR_MASK) /* Bus error occurs */ { DmaBusError = XTRUE; /* Set Dma Bus Error flag */ } if (StatusValue & XDMC_DMASR_BUS_TIMEOUT_MASK) /* Bus Timeout occurs */ { DmaBusTimeout = XTRUE; /* Set Dma Bus Timeout flag */ } } if (IntrStatusValue & XDMC_IXR_DMA_DONE_MASK) /* DMA Done Interrupt */ { /* * Set Dma Done flag so the code in application context can be aware * of the finished DMA transfer. */ DmaDone = XTRUE; } /* * Clear all bits in Interrupt Status Register. */ XDmaCentral_InterruptClear(DmaCentralPtr, IntrStatusValue);}void error(void){ while (1);}static void SrcDesWriteClear(XIo_Address SrcA, XIo_Address DesA){ xil_printf("\r\nStarting Writing and Clearing Source and Destination Addresses.\r\n"); int Index; for(Index = 0; Index < BUFFER_BYTESIZE; Index++) { XIo_Out32(SrcA, Index); XIo_Out32(DesA, 0); SrcA = SrcA + 4; DesA = DesA + 4; } xil_printf("\r\nFinished Writing and Clearing Source and Destination Addresses.\r\n");}static XStatus WaitForComp(){ /* Create a 32 bit variable to for the results of the interrupt register */ Xuint32 intreg; int i,j; xil_printf("\r\nWaiting"); while (1) { xil_printf("."); if (DmaBusError == XTRUE) /* Dma Bus Error occurs. */ { xil_printf("Bus error \r\n"); return XST_FAILURE; } if (DmaBusTimeout == XTRUE) /* Dma Bus Timeout occurs */ { xil_printf("Bus Timeout \r\n"); return XST_FAILURE; } if (DmaDone == XTRUE) /* Dma transfer is done */ { xil_printf("\r\n"); xil_printf("\r\nDMA Transfer Complete, Verifying Destination Data\r\n"); for (i=0;i<OPB_CENTRAL_DMA_LEN/4-1;i++) { j = *((volatile int *)(OPB_CENTRAL_DMA_DA+(4*i))); if (i != j) { xil_printf("Read from DMA Destination Address Failed %d \r\n", i); error(); } } xil_printf("\r\nDestination Data is Correct\r\n"); /* Check the interrupt register to see if it is cleared */ intreg = XDmaCentral_InterruptStatusGet(&DmaCentral); if(intreg == 0) { xil_printf("\r\nDMA Interrupt Cleared\r\n"); return XST_SUCCESS; } else { xil_printf("\r\n Interrupt Didn't Clear \r\n"); } } }} void GpioOutputExample(Xuint16 DeviceId, Xuint32 GpioWidth){ volatile int Delay; Xuint32 LedBit; Xuint32 LedLoop; XStatus Status; int numTimes = 6; /* * Initialize the GPIO driver so that it's ready to use, * specify the device ID that is generated in xparameters.h */ Status = XGpio_Initialize(&GpioOutput, DeviceId); if (Status != XST_SUCCESS) { print("Gpio Instance Didn't Initialize!\r\n"); error(); } /* * Set the direction for all signals to be outputs */ XGpio_SetDataDirection(&GpioOutput, 1, 0x0); /* * Set the GPIO outputs to low */ XGpio_DiscreteWrite(&GpioOutput, 1, 0x0); while (numTimes > 0) { for (LedBit = 0x0; LedBit < GpioWidth; LedBit++) { for (LedLoop = 0; LedLoop < 1; LedLoop++) { /* * Set the GPIO Output to High */ XGpio_DiscreteWrite(&GpioOutput, 1, 1 << LedBit); /* * Wait a small amount of time so the LED is visible */ for (Delay = 0; Delay < 1000000; Delay++); /* * Clear the GPIO Output */ XGpio_DiscreteClear(&GpioOutput, 1, 1 << LedBit); } } numTimes--; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -