Jun 10 2010

Xilinx Microblaze XDmaCentral DMA Controller

Dieses einfache Beispiel soll verdeutlichen wie man am einfachsten mit dem XCmaCentral XPS Central DMA Controller umgeht, es ist für ein Anfang bewusst einfach gehalten. Und kopiert Werte von einem Speicherbereich im SD oder DDR RAM in den anderen. Bei dem System ist darauf zu achten dass, Microblaze, DMA Controller (SPLB & MPLB) und Speicher im Xilinx Platform Studio (XPS) am gleichen Buss hängen. Ist man soweit kann man das Projekt für das Xilinx Software Development Kit (SDK) exportieren.

Beim programmieren des DMA gibt es ein paar kleine Stolperfallen.

  • bei XDmaCentral_SetControl sollte man sehr genau darauf achten Source und Destination nich zu vertauschen
  • XDmaCentral_Transfer will eine Angabe haben wie viele Byte er zu übertragen hat … das sind für eine 32 Bit Variable also 4 …

Sonst ist die Konfiguration sehr “straightforward”  ….

#include “xparameters.h”
#include “xintc.h”
#include “xdmacentral.h”
#define TEST_BUFFER_SIZE       20//4096

int main () {
static XDmaCentral dma;
Xuint32* Buffer;
Xuint32 *Buffer2;
Buffer = (Xuint32 *)0x8c000A00;
Buffer2 = (Xuint32 *)0x8c000000;
//(XPAR_DDR2_SDRAM_16MX32_MPMC_BASEADDR);

Xuint32 Index;
XStatus Status;

for (Index = 0; Index < TEST_BUFFER_SIZE; Index++)
{
Buffer[Index] = Index+41;
}

for (Index = 0; Index < TEST_BUFFER_SIZE; Index++)
{

xil_printf(“\n\r %x %d”,&Buffer[Index], Buffer[Index]);
}

Status = XDmaCentral_Initialize(&dma, XPAR_XPS_CENTRAL_DMA_0_DEVICE_ID);

if (Status != XST_SUCCESS)
{
xil_printf(“The Central DMA Didn’t Initialize! \r\n”);
return XST_FAILURE;
}
XDmaCentral_Reset(&dma);

XDmaCentral_SetControl(&dma,XDMC_DMACR_SOURCE_INCR_MASK
+XDMC_DMACR_DEST_INCR_MASK);
XDmaCentral_Transfer(&dma,(Xuint32 *) Buffer, (Xuint32 *) Buffer2, TEST_BUFFER_SIZE*4);

xil_printf(“\n\r Speicherzelle in Buffer %x wert an der stelle %d”,Buffer,*Buffer);
xil_printf(“\n\r Speicherzelle in Buffer %x wert an der stelle %d”,Buffer2,*Buffer2);

for (Index = 0; Index < TEST_BUFFER_SIZE; Index=Index+1)
{
xil_printf(“\n\r %x %d”,&Buffer2[Index],Buffer2[Index]);
}

xil_printf(“\r\nDone”);

return 0;

}

Das kleine Programm erzeugt ein Array im RAM welches dann vom DMA Controller in ein anders Umgespeichert wird. Im nächsten Schritt werde ich nun daran Arbeiten Daten mit dem Central DMA an und von meinem Ipif Modul zu übertragen. Der Central DMA kommt deswegen zum Einsatz da für den PLB4.6 kein IpIf Modul mit Integriertem DMA zur Verfügung steht. Siehe hier.


Feb 25 2010

Microblaze Xgpio interrupts

Leider sind die Beispiele betreffend Interrupts am Microblaze Softcore von Xilinx nicht gerade üppig gesät zumal wenn es um Xgpio geht. Dieses C Beispiel hilft hoffentlich ein wenig mit den Interrupts klar zu kommen. Laut der Xilinx Interrupt Dokumentation die schon ein paar Jahre auf dem Buckel hat (4 Jahre)  gibt es 2 Level auf denen die Interrupts angelegt werden können. Der unterste Level (LowLevel) ist in den *_l.h header files festgelegt. Dieser Level ist auch halbwegs gut beschrieben (in diesem Dokument und im Anhang B der Embedded System Tools Reference Manual) nur über den höher abstrahierten Level gibt es von Xilinx ein einziges Anwendungsbeispiel (und falls doch so habe ich es nicht gefunden) zugegebener maßen ist die API Dokumentation sehr gut … aber ein greifbares Beispiel wäre schon sehr Praktisch gewesen.
Gut jetzt gibts ja eins … nämlich meins … ich hoffe es Hilft.

Ich habe das Projekt mit dem BSB (Base System Builder)  erstellt und die Buttons und den Timer dort hinzugefühgt und als Interrupt Quellen angegeben. (das ist normal nicht Schwer)

Zum abgleichen gebe ich hier meine mit der EDK 10.1 erstellten MHS (Microprocessor Hardware Specification) MSS (Microprocessor Software Specification) files an.

MHS:
# #########################################################
# Created by Base System Builder Wizard for Xilinx EDK 10.1.03 Build EDK_K_SP3.6
# Wed Feb 24 10:37:29 2010
# Target Board:  Avnet Avnet V5FXT Evaluation Board Rev B
# Family:    virtex5
# Device:    xc5vfx30t
# Package:   ff665
# Speed Grade:  -1
# Processor: microblaze_0
# System clock frequency: 125.00 MHz
# On Chip Memory :  16 KB
# ########################################################
PARAMETER VERSION = 2.1.0

PORT fpga_0_RS232_USB_RX_pin = fpga_0_RS232_USB_RX, DIR = I
PORT fpga_0_RS232_USB_TX_pin = fpga_0_RS232_USB_TX, DIR = O
PORT fpga_0_RS232_USB_reset_dummy_pin = net_vcc, DIR = O
PORT fpga_0_LEDs_8Bit_GPIO_d_out_pin = fpga_0_LEDs_8Bit_GPIO_d_out, DIR = O, VEC = [0:7]
PORT fpga_0_Push_Buttons_3Bit_GPIO_in_pin = fpga_0_Push_Buttons_3Bit_GPIO_in, DIR = I, VEC = [0:2]
PORT sys_clk_pin = dcm_clk_s, DIR = I, SIGIS = CLK, CLK_FREQ = 100000000
PORT sys_rst_pin = sys_rst_s, DIR = I, RST_POLARITY = 1, SIGIS = RST

BEGIN microblaze
PARAMETER INSTANCE = microblaze_0
PARAMETER C_INTERCONNECT = 1
PARAMETER HW_VER = 7.10.d
PARAMETER C_DEBUG_ENABLED = 1
BUS_INTERFACE DLMB = dlmb
BUS_INTERFACE ILMB = ilmb
BUS_INTERFACE DPLB = mb_plb
BUS_INTERFACE IPLB = mb_plb
BUS_INTERFACE DEBUG = microblaze_0_dbg
PORT MB_RESET = mb_reset
PORT Interrupt = Interrupt
END

BEGIN plb_v46
PARAMETER INSTANCE = mb_plb
PARAMETER HW_VER = 1.03.a
PORT PLB_Clk = sys_clk_s
PORT SYS_Rst = sys_bus_reset
END

BEGIN lmb_v10
PARAMETER INSTANCE = ilmb
PARAMETER HW_VER = 1.00.a
PORT LMB_Clk = sys_clk_s
PORT SYS_Rst = sys_bus_reset
END

BEGIN lmb_v10
PARAMETER INSTANCE = dlmb
PARAMETER HW_VER = 1.00.a
PORT LMB_Clk = sys_clk_s
PORT SYS_Rst = sys_bus_reset
END

BEGIN lmb_bram_if_cntlr
PARAMETER INSTANCE = dlmb_cntlr
PARAMETER HW_VER = 2.10.a
PARAMETER C_BASEADDR = 0×00000000
PARAMETER C_HIGHADDR = 0x00003fff
BUS_INTERFACE SLMB = dlmb
BUS_INTERFACE BRAM_PORT = dlmb_port
END

BEGIN lmb_bram_if_cntlr
PARAMETER INSTANCE = ilmb_cntlr
PARAMETER HW_VER = 2.10.a
PARAMETER C_BASEADDR = 0×00000000
PARAMETER C_HIGHADDR = 0x00003fff
BUS_INTERFACE SLMB = ilmb
BUS_INTERFACE BRAM_PORT = ilmb_port
END

BEGIN bram_block
PARAMETER INSTANCE = lmb_bram
PARAMETER HW_VER = 1.00.a
BUS_INTERFACE PORTA = ilmb_port
BUS_INTERFACE PORTB = dlmb_port
END

BEGIN xps_uartlite
PARAMETER INSTANCE = RS232_USB
PARAMETER HW_VER = 1.00.a
PARAMETER C_BAUDRATE = 9600
PARAMETER C_DATA_BITS = 8
PARAMETER C_ODD_PARITY = 0
PARAMETER C_USE_PARITY = 0
PARAMETER C_SPLB_CLK_FREQ_HZ = 125000000
PARAMETER C_BASEADDR = 0×84000000
PARAMETER C_HIGHADDR = 0x8400ffff
BUS_INTERFACE SPLB = mb_plb
PORT RX = fpga_0_RS232_USB_RX
PORT TX = fpga_0_RS232_USB_TX
END

BEGIN xps_gpio
PARAMETER INSTANCE = LEDs_8Bit
PARAMETER HW_VER = 1.00.a
PARAMETER C_GPIO_WIDTH = 8
PARAMETER C_IS_DUAL = 0
PARAMETER C_IS_BIDIR = 0
PARAMETER C_ALL_INPUTS = 0
PARAMETER C_BASEADDR = 0×81400000
PARAMETER C_HIGHADDR = 0x8140ffff
BUS_INTERFACE SPLB = mb_plb
PORT GPIO_d_out = fpga_0_LEDs_8Bit_GPIO_d_out
END

BEGIN xps_gpio
PARAMETER INSTANCE = Push_Buttons_3Bit
PARAMETER HW_VER = 1.00.a
PARAMETER C_INTERRUPT_PRESENT = 1
PARAMETER C_GPIO_WIDTH = 3
PARAMETER C_IS_DUAL = 0
PARAMETER C_IS_BIDIR = 0
PARAMETER C_ALL_INPUTS = 1
PARAMETER C_BASEADDR = 0×81420000
PARAMETER C_HIGHADDR = 0x8142ffff
BUS_INTERFACE SPLB = mb_plb
PORT GPIO_in = fpga_0_Push_Buttons_3Bit_GPIO_in
PORT IP2INTC_Irpt = Push_Buttons_3Bit_IP2INTC_Irpt
END

BEGIN xps_timer
PARAMETER INSTANCE = xps_timer_1
PARAMETER HW_VER = 1.00.a
PARAMETER C_COUNT_WIDTH = 32
PARAMETER C_ONE_TIMER_ONLY = 1
PARAMETER C_BASEADDR = 0x83c00000
PARAMETER C_HIGHADDR = 0x83c0ffff
BUS_INTERFACE SPLB = mb_plb
PORT Interrupt = xps_timer_1_Interrupt
END

BEGIN clock_generator
PARAMETER INSTANCE = clock_generator_0
PARAMETER HW_VER = 2.01.a
PARAMETER C_EXT_RESET_HIGH = 1
PARAMETER C_CLKIN_FREQ = 100000000
PARAMETER C_CLKOUT0_FREQ = 125000000
PARAMETER C_CLKOUT0_BUF = TRUE
PARAMETER C_CLKOUT0_PHASE = 0
PARAMETER C_CLKOUT0_GROUP = NONE
PORT CLKOUT0 = sys_clk_s
PORT CLKIN = dcm_clk_s
PORT LOCKED = Dcm_all_locked
PORT RST = net_gnd
END

BEGIN mdm
PARAMETER INSTANCE = debug_module
PARAMETER HW_VER = 1.00.d
PARAMETER C_MB_DBG_PORTS = 1
PARAMETER C_USE_UART = 1
PARAMETER C_UART_WIDTH = 8
PARAMETER C_BASEADDR = 0×84400000
PARAMETER C_HIGHADDR = 0x8440ffff
BUS_INTERFACE SPLB = mb_plb
BUS_INTERFACE MBDEBUG_0 = microblaze_0_dbg
PORT Debug_SYS_Rst = Debug_SYS_Rst
END

BEGIN proc_sys_reset
PARAMETER INSTANCE = proc_sys_reset_0
PARAMETER HW_VER = 2.00.a
PARAMETER C_EXT_RESET_HIGH = 1
PORT Slowest_sync_clk = sys_clk_s
PORT Dcm_locked = Dcm_all_locked
PORT Ext_Reset_In = sys_rst_s
PORT MB_Reset = mb_reset
PORT Bus_Struct_Reset = sys_bus_reset
PORT MB_Debug_Sys_Rst = Debug_SYS_Rst
PORT Peripheral_Reset = sys_periph_reset
END

BEGIN xps_intc
PARAMETER INSTANCE = xps_intc_0
PARAMETER HW_VER = 1.00.a
PARAMETER C_BASEADDR = 0×81800000
PARAMETER C_HIGHADDR = 0x8180ffff
BUS_INTERFACE SPLB = mb_plb
PORT Irq = Interrupt
PORT Intr = Push_Buttons_3Bit_IP2INTC_Irpt & xps_timer_1_Interrupt
END

MSS:
PARAMETER VERSION = 2.2.0

BEGIN OS
PARAMETER OS_NAME = standalone
PARAMETER OS_VER = 2.00.a
PARAMETER PROC_INSTANCE = microblaze_0
PARAMETER STDIN = RS232_USB
PARAMETER STDOUT = RS232_USB
END

BEGIN PROCESSOR
PARAMETER DRIVER_NAME = cpu
PARAMETER DRIVER_VER = 1.11.b
PARAMETER HW_INSTANCE = microblaze_0
PARAMETER COMPILER = mb-gcc
PARAMETER ARCHIVER = mb-ar
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = bram
PARAMETER DRIVER_VER = 1.00.a
PARAMETER HW_INSTANCE = dlmb_cntlr
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = bram
PARAMETER DRIVER_VER = 1.00.a
PARAMETER HW_INSTANCE = ilmb_cntlr
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 1.00.a
PARAMETER HW_INSTANCE = lmb_bram
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = uartlite
PARAMETER DRIVER_VER = 1.13.a
PARAMETER HW_INSTANCE = RS232_USB
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = gpio
PARAMETER DRIVER_VER = 2.12.a
PARAMETER HW_INSTANCE = LEDs_8Bit
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = gpio
PARAMETER DRIVER_VER = 2.12.a
PARAMETER HW_INSTANCE = Push_Buttons_3Bit
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = tmrctr
PARAMETER DRIVER_VER = 1.10.b
PARAMETER HW_INSTANCE = xps_timer_1
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 1.00.a
PARAMETER HW_INSTANCE = clock_generator_0
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = uartlite
PARAMETER DRIVER_VER = 1.13.a
PARAMETER HW_INSTANCE = debug_module
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = generic
PARAMETER DRIVER_VER = 1.00.a
PARAMETER HW_INSTANCE = proc_sys_reset_0
END

BEGIN DRIVER
PARAMETER DRIVER_NAME = intc
PARAMETER DRIVER_VER = 1.11.a
PARAMETER HW_INSTANCE = xps_intc_0
END

Das C Progamme zur verarbeitung der Interrupts:

#include <xtmrctr.h>
#include <xintc.h>
#include <xgpio.h>
#include <xparameters.h>

XGpio gpio, buttons;
XIntc intc;
XTmrCtr timer;

void buttons_int_handler(void * baseaddr_p) {
//xil_printf(“Button!\r\n\n”);
unsigned int csr;
/* Read Button CSR to see if it raised the interrupt */
csr = XTmrCtr_mGetControlStatusReg (XPAR_PUSH_BUTTONS_3BIT_BASEADDR, 0);
xil_printf(“csr=%d\r\n”,csr);

switch(csr) {

case 0×01:
xil_printf(“SW4\r\n”);
break;

case 0×02:
xil_printf(“SW3\r\n”);
break;

case 0×04:
xil_printf(“SW2\r\n”);
break;

default : {
}

}

//Clear the interrupt both in the Gpio instance as well as the interrupt controlle
XGpio_InterruptClear(&buttons, 0×3);
XIntc_Acknowledge (&intc, XPAR_XPS_INTC_0_PUSH_BUTTONS_3BIT_IP2INTC_IRPT_INTR);
xil_printf(“Interrupt Cleared\r\n”);

}

void timer_int_handler(void * baseaddr_p) {
unsigned int csr;
/* Read timer 0 CSR to see if it raised the interrupt */
csr = XTmrCtr_mGetControlStatusReg (XPAR_XPS_TIMER_1_BASEADDR, 0);
/* If the interrupt occurred, then increment a counter */
if (csr & XTC_CSR_INT_OCCURED_MASK)
{
count++;
}
print (“Timer Interrupt\r\n”);
xil_printf (“Count Sagt: %d Interrupts \r\n”,count);

/* Clear the timer interrupt */
XTmrCtr_mSetControlStatusReg (XPAR_XPS_TIMER_1_BASEADDR, 0, csr); //Still Level 0 Macro
}

int main()/*the one and only*/ {

microblaze_enable_interrupts();
xil_printf(“MB interrupts\t\t Enabled\r\n”);

Xuint32 status;
//Interr Init
status=XIntc_Initialize (&intc, XPAR_XPS_INTC_0_DEVICE_ID);
if (status != XST_SUCCESS){
xil_printf(“init INTC_0\t Error \r\n”);
return XST_FAILURE;
}
else xil_printf(“init INTC_0\t\t OK \r\n”);

//Button Init Stuff

status=XGpio_Initialize (&buttons, XPAR_PUSH_BUTTONS_3BIT_DEVICE_ID);
if (status != XST_SUCCESS){
xil_printf(“init Buttons\t\t Error \r\n”);
return XST_FAILURE;
}
else xil_printf(“init Buttons\t\t OK \r\n”);

XGpio_SetDataDirection(&buttons, 1, 0xFFFFFFFF);
xil_printf(“Buttons Direction\t Set\r\n”);

//Timer Init Stuff

status=XTmrCtr_Initialize (&timer, XPAR_XPS_TIMER_1_DEVICE_ID);
if (status != XST_SUCCESS){
xil_printf(“init Timer\t\t Error \r\n”);
return XST_FAILURE;
}
else xil_printf(“init Timer\t\t OK \r\n”);

//buttons
status=XIntc_Connect (&intc, XPAR_XPS_INTC_0_PUSH_BUTTONS_3BIT_IP2INTC_IRPT_INTR,
&buttons_int_handler, (void *)0);

if (status != XST_SUCCESS){
xil_printf(“connect buttons\t\t Error \r\n”);
return XST_FAILURE;
}
else xil_printf(“connect buttons\t\t OK \r\n”);

//Timer Options

XTmrCtr_SetOptions(&timer, 0,        //for timer #0 (there are 2 timers in the led_timer device, we’re only using one)
XTC_DOWN_COUNT_OPTION |     // Count down to 0
XTC_INT_MODE_OPTION |         // When it hits 0, cause an interrupt
XTC_AUTO_RELOAD_OPTION);    // And reload the “reset” value and begin counting again

xil_printf(“Timer Setting\t\t Set\r\n”);

//Timer
status=XIntc_Connect (&intc, XPAR_XPS_INTC_0_XPS_TIMER_1_INTERRUPT_INTR, &timer_int_handler, (void*)0);

if (status != XST_SUCCESS){
xil_printf(“connect timer\t\t Error\r\n”);
return XST_FAILURE;
}
else xil_printf(“connect timer\t\t OK\r\n”);

XIntc_Enable (&intc, XPAR_PUSH_BUTTONS_3BIT_DEVICE_ID);
xil_printf(“Button interrupt\t Enabled\r\n”);

XIntc_Enable (&intc, XPAR_XPS_TIMER_1_DEVICE_ID);
xil_printf(“Timer interrupt\t\t Enabled\r\n”);

//Enable Xgpio Interrupt Stuff ans so on …

//XGpio_InterruptClear(buttons, XGPIO_IR_CH1_MASK);
xil_printf(“Buttons Interrupt\t NOT Cleared YET\r\n”);

XGpio_InterruptEnable (&buttons, XPAR_XPS_INTC_0_PUSH_BUTTONS_3BIT_IP2INTC_IRPT_INTR);
xil_printf(“XGpio interrupt\t\t Enabled\r\n”);
XGpio_InterruptGlobalEnable (&buttons);
xil_printf(“XGpio Global interrupt\t Enabled\r\n”);

status=XIntc_Start (&intc ,XIN_REAL_MODE);

if (status != XST_SUCCESS){
xil_printf(“start xintc\t\t Error\r\n”);
return XST_FAILURE;
}
else xil_printf(“start xintc\t\t OK\r\n”);

//Load Value 4 the Timer
XTmrCtr_SetResetValue(&timer, 0, 1000000000);
//Start the timer
XTmrCtr_Start (&timer,0);

xil_printf(“<—Entering WHILE(1);—>\r\n”);

while(1);

}

Beim erstellen des Codes haben die Beispiele die auch beide schon ein wenig älter sein dürften (ca. 3 Jahre) hier und hier sehr geholfen.
Ich hoffe ihr könnt mit meinem Code fetzen etwas anfangen über Kommentare würde ich mich sehr freuen.
Die Ausgaben des Progammes erfolgen über stdout (je nach dem wie er konfiguriert ist über Usb (virtueller Com Port) oder direkt über RS232.
Für mein Beispiel ist das Hyperterminal (Windows Zubehör/ Kommunikation) auf 9600 Baud, 8 Datenbits, Ohne Parität, mit einem Stoppbit und ohne Flusssteuerung zu konfigurieren (BSB default iirr). Getestet habe ich es auf einem Avnet Virtex5 Board.

#include <xtmrctr.h>
#include <xintc.h>
#include <xgpio.h>
#include <xparameters.h>

XGpio gpio, buttons;
XIntc intc;
XTmrCtr timer;

void buttons_int_handler(void * baseaddr_p) {
//xil_printf(“Button!\r\n\n”);
unsigned int csr;
/* Read Button CSR to see if it raised the interrupt */
csr = XTmrCtr_mGetControlStatusReg (XPAR_PUSH_BUTTONS_3BIT_BASEADDR, 0);
xil_printf(“csr=%d\r\n”,csr);

switch(csr) {

case 0×01:
xil_printf(“SW4\r\n”);
break;

case 0×02:
xil_printf(“SW3\r\n”);
break;

case 0×04:
xil_printf(“SW2\r\n”);
break;

default : {
}

}

//Clear the interrupt both in the Gpio instance as well as the interrupt controlle
XGpio_InterruptClear(&buttons, 0×3);
XIntc_Acknowledge (&intc, XPAR_XPS_INTC_0_PUSH_BUTTONS_3BIT_IP2INTC_IRPT_INTR);
xil_printf(“Interrupt Cleared\r\n”);

}

void timer_int_handler(void * baseaddr_p) {
unsigned int csr;
/* Read timer 0 CSR to see if it raised the interrupt */
csr = XTmrCtr_mGetControlStatusReg (XPAR_XPS_TIMER_1_BASEADDR, 0);
/* If the interrupt occurred, then increment a counter */
if (csr & XTC_CSR_INT_OCCURED_MASK)
{
count++;
}
print (“Timer Interrupt\r\n”);
xil_printf (“Count Sagt: %d Interrupts \r\n”,count);

/* Clear the timer interrupt */
XTmrCtr_mSetControlStatusReg (XPAR_XPS_TIMER_1_BASEADDR, 0, csr); //Still Level 0 Macro
}

int main()/*the one and only*/ {

microblaze_enable_interrupts();
xil_printf(“MB interrupts\t\t Enabled\r\n”);

Xuint32 status;
//Interr Init
status=XIntc_Initialize (&intc, XPAR_XPS_INTC_0_DEVICE_ID);
if (status != XST_SUCCESS){
xil_printf(“init INTC_0\t Error \r\n”);
return XST_FAILURE;
}
else xil_printf(“init INTC_0\t\t OK \r\n”);

//Button Init Stuff

status=XGpio_Initialize (&buttons, XPAR_PUSH_BUTTONS_3BIT_DEVICE_ID);
if (status != XST_SUCCESS){
xil_printf(“init Buttons\t\t Error \r\n”);
return XST_FAILURE;
}
else xil_printf(“init Buttons\t\t OK \r\n”);

XGpio_SetDataDirection(&buttons, 1, 0xFFFFFFFF);
xil_printf(“Buttons Direction\t Set\r\n”);

//Timer Init Stuff

status=XTmrCtr_Initialize (&timer, XPAR_XPS_TIMER_1_DEVICE_ID);
if (status != XST_SUCCESS){
xil_printf(“init Timer\t\t Error \r\n”);
return XST_FAILURE;
}
else xil_printf(“init Timer\t\t OK \r\n”);

//buttons
status=XIntc_Connect (&intc, XPAR_XPS_INTC_0_PUSH_BUTTONS_3BIT_IP2INTC_IRPT_INTR,
&buttons_int_handler, (void *)0);

if (status != XST_SUCCESS){
xil_printf(“connect buttons\t\t Error \r\n”);
return XST_FAILURE;
}
else xil_printf(“connect buttons\t\t OK \r\n”);

//Timer Options

XTmrCtr_SetOptions(&timer, 0,        //for timer #0 (there are 2 timers in the led_timer device, we’re only using one)
XTC_DOWN_COUNT_OPTION |     // Count down to 0
XTC_INT_MODE_OPTION |         // When it hits 0, cause an interrupt
XTC_AUTO_RELOAD_OPTION);    // And reload the “reset” value and begin counting again

xil_printf(“Timer Setting\t\t Set\r\n”);

//Timer
status=XIntc_Connect (&intc, XPAR_XPS_INTC_0_XPS_TIMER_1_INTERRUPT_INTR, &timer_int_handler, (void*)0);

if (status != XST_SUCCESS){
xil_printf(“connect timer\t\t Error\r\n”);
return XST_FAILURE;
}
else xil_printf(“connect timer\t\t OK\r\n”);

XIntc_Enable (&intc, XPAR_PUSH_BUTTONS_3BIT_DEVICE_ID);
xil_printf(“Button interrupt\t Enabled\r\n”);

XIntc_Enable (&intc, XPAR_XPS_TIMER_1_DEVICE_ID);
xil_printf(“Timer interrupt\t\t Enabled\r\n”);

//Enable Xgpio Interrupt Stuff ans so on …

//XGpio_InterruptClear(buttons, XGPIO_IR_CH1_MASK);
xil_printf(“Buttons Interrupt\t NOT Cleared YET\r\n”);

XGpio_InterruptEnable (&buttons, XPAR_XPS_INTC_0_PUSH_BUTTONS_3BIT_IP2INTC_IRPT_INTR);
xil_printf(“XGpio interrupt\t\t Enabled\r\n”);
XGpio_InterruptGlobalEnable (&buttons);
xil_printf(“XGpio Global interrupt\t Enabled\r\n”);

status=XIntc_Start (&intc ,XIN_REAL_MODE);

if (status != XST_SUCCESS){
xil_printf(“start xintc\t\t Error\r\n”);
return XST_FAILURE;
}
else xil_printf(“start xintc\t\t OK\r\n”);

//Load Value 4 the Timer
XTmrCtr_SetResetValue(&timer, 0, 1000000000);
//Start the timer
XTmrCtr_Start (&timer,0);

xil_printf(“<—Entering WHILE(1);—>\r\n”);

while(1);

}