Memory Space Access
This HowTo discusses some aspects of accessing locations with the memory address space. This may be both memory blocks or memory mapped peripherals.
Note: This HowTo uses Xilinx EDK version 9.1i
Memory IO Code
Accessing devices connected to the processor comes down to a couple of functions XIo_Out32
and XIo_In32
. These are actually predefined macros rather than functions. They are
defined in xio.h
. The file can be found in the EDK installation. The macros are shown
below.
$XILINX_EDK/sw/XilinxProcessorIPLib/drivers/cpu_v1_01_a/src/xio.h
#define XIo_Out32(OutputPtr, Value) \ (*(volatile Xuint32 *)((OutputPtr)) = (Value)) #define XIo_In32(InputPtr) (*(volatile Xuint32 *)(InputPtr))
You can use the macros, or declare your own memory pointers. Both methods are shown below for a memory write. In this case XPAR_OPB_TEST_0_BASEADDR is the base address of a OPB based peripheral.
exp1.c
#include "xparameters.h" #include "xutil.h" #include "xio.h" int main(void) { Xuint32 dataOut = 0x1234ABCD; // Write using memory pointer volatile Xuint32 *dataPointer; dataPointer = (volatile Xuint32 *) XPAR_OPB_TEST_0_BASEADDR; *dataPointer = dataOut; // Write using the macro XIo_Out32(XPAR_OPB_TEST_0_BASEADDR, dataOut); return 0; }
Either approach will compile down to the same thing. So do whatever is easier and the most intuitive.
Memory Address Offsets
The OPB and PLB are addressed on a byte basis, but has a 32bit wide data bus. Therefore to access 32bit chunks of your peripheral you'll need to add multiples of 4 to the peripherals base address.
OPB address offsets
exp1.c
#include "xparameters.h" #include "xutil.h" #include "xio.h" int main(void) { print("Starting OPB Test\n"); Xuint32 dataIn; XIo_Out32(XPAR_OPB_TEST_0_BASEADDR, 0x1234ABCD); XIo_Out32(XPAR_OPB_TEST_0_BASEADDR+4, 0xFFEEFFEE); XIo_Out32(XPAR_OPB_TEST_0_BASEADDR+8, 0x80000001); XIo_Out32(XPAR_OPB_TEST_0_BASEADDR+12, 0x76543210); dataIn = XIo_In32(XPAR_OPB_TEST_0_BASEADDR); xil_printf("In: %08X\n", dataIn); dataIn = XIo_In32(XPAR_OPB_TEST_0_BASEADDR+4); xil_printf("In: %08X\n", dataIn); dataIn = XIo_In32(XPAR_OPB_TEST_0_BASEADDR+8); xil_printf("In: %08X\n", dataIn); dataIn = XIo_In32(XPAR_OPB_TEST_0_BASEADDR+12); xil_printf("In: %08X\n", dataIn); return 0; }