From 12b49eff1cd3099e95b5e3b22fd6c37d4247d229 Mon Sep 17 00:00:00 2001 From: Dreaded_X Date: Thu, 28 Jan 2021 22:47:06 +0100 Subject: [PATCH] Whole project can now be build using make --- .gitignore | 1 - Makefile | 53 +++++++ controller.elf | Bin 15556 -> 0 bytes build.tcl => scripts/build.tcl | 14 +- scripts/clk_wiz_0.tcl | 50 ++++++ scripts/microblaze_mcs_0.tcl | 36 +++++ scripts/sdk.tcl | 9 ++ write.tcl => scripts/write.tcl | 0 software/src/lscript.ld | 212 ++++++++++++++++++++++++++ software/src/main.c | 268 +++++++++++++++++++++++++++++++++ 10 files changed, 635 insertions(+), 8 deletions(-) create mode 100644 Makefile delete mode 100755 controller.elf rename build.tcl => scripts/build.tcl (94%) create mode 100644 scripts/clk_wiz_0.tcl create mode 100644 scripts/microblaze_mcs_0.tcl create mode 100644 scripts/sdk.tcl rename write.tcl => scripts/write.tcl (100%) create mode 100644 software/src/lscript.ld create mode 100644 software/src/main.c diff --git a/.gitignore b/.gitignore index eab3b43..495f775 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ .build .Xil -hdmi.sdk diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5508e2f --- /dev/null +++ b/Makefile @@ -0,0 +1,53 @@ +BUILD = .build + +VERILOG = \ +src/char_map.v \ +src/color_map.v \ +src/dvi_top.v \ +src/dvid.v \ +src/encode.v \ +src/hdmi.xdc \ +src/simple_dual_ram.v \ + +.PHONY: all clean + +all: $(BUILD)/impl.bin + +$(BUILD)/ip/clk_wiz_0/clk_wiz_0.xci: scripts/clk_wiz_0.tcl | $(BUILD)/ip + /opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/clk_wiz_0.tcl -nolog -nojournal + +$(BUILD)/ip/microblaze_mcs_0/microblaze_mcs_0.xci: scripts/microblaze_mcs_0.tcl | $(BUILD)/ip + /opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/microblaze_mcs_0.tcl -nolog -nojournal + +$(BUILD)/5_route.dcp: $(VERILOG) $(BUILD)/ip/clk_wiz_0/clk_wiz_0.xci $(BUILD)/ip/microblaze_mcs_0/microblaze_mcs_0.xci scripts/build.tcl | $(BUILD) + /opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/build.tcl -nolog -nojournal + +$(BUILD)/impl.bin: $(BUILD)/5_route.dcp $(BUILD)/controller.elf scripts/write.tcl | $(BUILD) + /opt/Xilinx/Vivado/2019.1/bin/vivado -mode batch -source scripts/write.tcl -nolog -nojournal + +$(BUILD)/bsp/system.mss: $(BUILD)/system.hdf | $(BUILD) + /opt/Xilinx/SDK/2019.1/bin/xsdk -batch scripts/sdk.tcl + +$(BUILD)/bsp/microblaze_I/lib/libxil.a: $(BUILD)/bsp/system.mss + $(MAKE) -C $(BUILD)/bsp all + +OBJ = \ +$(BUILD)/obj/main.o + +$(BUILD)/obj/%.o: software/src/%.c $(BUILD)/bsp/microblaze_I/lib/libxil.a | $(BUILD)/obj + mb-gcc -Wall -O2 -c -fmessage-length=0 -MT"$@" -I$(BUILD)/bsp/microblaze_I/include -mno-xl-reorder -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -ffunction-sections -fdata-sections -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@)" -o "$@" "$<" + +$(BUILD)/controller.elf: $(OBJ) software/src/lscript.ld $(BUILD)/bsp/microblaze_I/lib/libxil.a | $(BUILD) + mb-gcc -Wl,-T -Wl,software/src/lscript.ld -L$(BUILD)/bsp/microblaze_I/lib -mlittle-endian -mcpu=v11.0 -mxl-soft-mul -Wl,--no-relax -Wl,--gc-sections -o "$@" $(OBJ) -Wl,--start-group,-lxil,-lgcc,-lc,--end-group + +$(BUILD): + mkdir $@ + +$(BUILD)/ip: | $(BUILD) + mkdir $@ + +$(BUILD)/obj: | $(BUILD) + mkdir $@ + +clean: + rm -fr $(BUILD) diff --git a/controller.elf b/controller.elf deleted file mode 100755 index 8fab699f32980a38040d47fe10342ad27608e26d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15556 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 BL8brz diff --git a/build.tcl b/scripts/build.tcl similarity index 94% rename from build.tcl rename to scripts/build.tcl index fad523d..9b2b0f5 100644 --- a/build.tcl +++ b/scripts/build.tcl @@ -10,17 +10,17 @@ foreach fname [glob -nocomplain -type f $out_dir/*] { } set step 0_ip -if { [file isdirectory ./.build/ip] } { - read_ip ./.build/ip/clk_wiz_0/clk_wiz_0.xci - read_ip ./.build/ip/microblaze_mcs_0/microblaze_mcs_0.xci +if { [file isdirectory ${out_dir}/ip] } { + read_ip ${out_dir}/ip/clk_wiz_0/clk_wiz_0.xci + read_ip ${out_dir}/ip/microblaze_mcs_0/microblaze_mcs_0.xci } else { - file mkdir ./.build/ip + file mkdir ${out_dir}/ip create_project -in_memory create_ip -name clk_wiz -vendor xilinx.com -library ip \ -version 6.0 -module_name clk_wiz_0 \ - -dir ./.build/ip + -dir ${out_dir}/ip set_property -dict [list \ CONFIG.PRIMARY_PORT {clk_in} \ @@ -58,7 +58,7 @@ if { [file isdirectory ./.build/ip] } { create_ip -name microblaze_mcs -vendor xilinx.com -library ip \ -version 3.0 -module_name microblaze_mcs_0 \ - -dir ./.build/ip + -dir ${out_dir}/ip set_property -dict [list \ CONFIG.FREQ {150} \ @@ -134,4 +134,4 @@ report_drc -file $out_dir/${step}_drc.rpt write_verilog -force $out_dir/imp_netlist.v write_xdc -no_fixed_only -force $out_dir/imp.xdc -source write.tcl +write_hwdef -force -file ${out_dir}/system.hdf diff --git a/scripts/clk_wiz_0.tcl b/scripts/clk_wiz_0.tcl new file mode 100644 index 0000000..abe8250 --- /dev/null +++ b/scripts/clk_wiz_0.tcl @@ -0,0 +1,50 @@ +set out_dir ./.build +set part_num xc7a35tftg256-1 + +set_part $part_num + +file delete -force $out_dir/ip/clk_wiz_0 + +create_project -in_memory + +create_ip -name clk_wiz -vendor xilinx.com -library ip \ + -version 6.0 -module_name clk_wiz_0 \ + -dir ${out_dir}/ip + +set_property -dict [list \ + CONFIG.PRIMARY_PORT {clk_in} \ + CONFIG.CLKOUT2_USED {true} \ + CONFIG.CLKOUT3_USED {true} \ + CONFIG.CLKOUT4_USED {true} \ + CONFIG.CLK_OUT1_PORT {clk_dvi} \ + CONFIG.CLK_OUT2_PORT {clk_dvin} \ + CONFIG.CLK_OUT3_PORT {clk_pix} \ + CONFIG.CLK_OUT4_PORT {clk_mcu} \ + CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {375} \ + CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {375} \ + CONFIG.CLKOUT2_REQUESTED_PHASE {180} \ + CONFIG.CLKOUT3_REQUESTED_OUT_FREQ {75} \ + CONFIG.CLKOUT4_REQUESTED_OUT_FREQ {150} \ + CONFIG.CLKOUT1_DRIVES {BUFG} \ + CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} \ + CONFIG.MMCM_DIVCLK_DIVIDE {1} \ + CONFIG.MMCM_CLKFBOUT_MULT_F {7.500} \ + CONFIG.MMCM_CLKOUT0_DIVIDE_F {2.000} \ + CONFIG.MMCM_CLKOUT1_DIVIDE {2} \ + CONFIG.MMCM_CLKOUT1_PHASE {180.000} \ + CONFIG.MMCM_CLKOUT2_DIVIDE {10} \ + CONFIG.MMCM_CLKOUT3_DIVIDE {5} \ + CONFIG.NUM_OUT_CLKS {4} \ + CONFIG.CLKOUT1_JITTER {111.604} \ + CONFIG.CLKOUT1_PHASE_ERROR {116.405} \ + CONFIG.CLKOUT2_JITTER {111.604} \ + CONFIG.CLKOUT2_PHASE_ERROR {116.405} \ + CONFIG.CLKOUT3_JITTER {152.549} \ + CONFIG.CLKOUT3_PHASE_ERROR {116.405} \ + CONFIG.CLKOUT4_JITTER {132.464} \ + CONFIG.CLKOUT4_PHASE_ERROR {116.405} \ +] [get_ips clk_wiz_0] + +generate_target all [get_ips] + +synth_ip [get_ips] > $out_dir/clk_wiz_0.log diff --git a/scripts/microblaze_mcs_0.tcl b/scripts/microblaze_mcs_0.tcl new file mode 100644 index 0000000..937edc2 --- /dev/null +++ b/scripts/microblaze_mcs_0.tcl @@ -0,0 +1,36 @@ +set out_dir ./.build +set part_num xc7a35tftg256-1 + +set_part $part_num + +file delete -force $out_dir/ip/microblaze_mcs_0 + +create_project -in_memory + +create_ip -name microblaze_mcs -vendor xilinx.com -library ip \ + -version 3.0 -module_name microblaze_mcs_0 \ + -dir ${out_dir}/ip + +set_property -dict [list \ + CONFIG.FREQ {150} \ + CONFIG.MEMSIZE {131072} \ + CONFIG.USE_GPO1 {1} \ + CONFIG.GPO1_SIZE {16} \ + CONFIG.USE_GPO2 {1} \ + CONFIG.GPO2_SIZE {16} \ + CONFIG.USE_GPO3 {1} \ + CONFIG.GPO3_SIZE {2} \ + CONFIG.USE_GPO4 {1} \ + CONFIG.GPO4_SIZE {6} \ + CONFIG.USE_GPI1 {1} \ + CONFIG.GPI1_SIZE {8} \ + CONFIG.USE_GPI2 {1} \ + CONFIG.GPI2_SIZE {1} \ + CONFIG.GPI2_INTERRUPT {3} \ + CONFIG.USE_GPI3 {1} \ + CONFIG.GPI3_SIZE {1} \ +] [get_ips microblaze_mcs_0] + +generate_target all [get_ips] + +synth_ip [get_ips] > $out_dir/microblaze_mcs_0.log diff --git a/scripts/sdk.tcl b/scripts/sdk.tcl new file mode 100644 index 0000000..0389775 --- /dev/null +++ b/scripts/sdk.tcl @@ -0,0 +1,9 @@ +set out_dir ./.build + +file delete -force ${out_dir}/.metadata +file delete -force ${out_dir}/hw_platform +file delete -force ${out_dir}/bsp + +setws .build +createhw -name hw_platform -hwspec .build/system.hdf +createbsp -name bsp -hwproject hw_platform -os standalone -proc microblaze_I diff --git a/write.tcl b/scripts/write.tcl similarity index 100% rename from write.tcl rename to scripts/write.tcl diff --git a/software/src/lscript.ld b/software/src/lscript.ld new file mode 100644 index 0000000..7f7d4ee --- /dev/null +++ b/software/src/lscript.ld @@ -0,0 +1,212 @@ +/*******************************************************************/ +/* */ +/* This file is automatically generated by linker script generator.*/ +/* */ +/* Version: 2019.1 */ +/* */ +/* Copyright (c) 2010-2016 Xilinx, Inc. All rights reserved. */ +/* */ +/* Description : MicroBlaze Linker Script */ +/* */ +/*******************************************************************/ + +_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x400; +_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x800; + +/* Define Memories in the system */ + +MEMORY +{ + ilmb_cntlr_Mem_dlmb_cntlr_Mem : ORIGIN = 0x50, LENGTH = 0x7FB0 +} + +/* Specify the default entry point to the program */ + +ENTRY(_start) + +/* Define the sections, and where they are mapped in memory */ + +SECTIONS +{ +.vectors.reset 0x0 : { + KEEP (*(.vectors.reset)) +} + +.vectors.sw_exception 0x8 : { + KEEP (*(.vectors.sw_exception)) +} + +.vectors.interrupt 0x10 : { + KEEP (*(.vectors.interrupt)) +} + +.vectors.hw_exception 0x20 : { + KEEP (*(.vectors.hw_exception)) +} + +.text : { + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.init : { + KEEP (*(.init)) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.fini : { + KEEP (*(.fini)) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.ctors : { + __CTOR_LIST__ = .; + ___CTORS_LIST___ = .; + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + ___CTORS_END___ = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.dtors : { + __DTOR_LIST__ = .; + ___DTORS_LIST___ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + PROVIDE(__DTOR_END__ = .); + PROVIDE(___DTORS_END___ = .); +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.rodata : { + __rodata_start = .; + *(.rodata) + *(.rodata.*) + *(.gnu.linkonce.r.*) + __rodata_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.sdata2 : { + . = ALIGN(8); + __sdata2_start = .; + *(.sdata2) + *(.sdata2.*) + *(.gnu.linkonce.s2.*) + . = ALIGN(8); + __sdata2_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.sbss2 : { + __sbss2_start = .; + *(.sbss2) + *(.sbss2.*) + *(.gnu.linkonce.sb2.*) + __sbss2_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.data : { + . = ALIGN(4); + __data_start = .; + *(.data) + *(.data.*) + *(.gnu.linkonce.d.*) + __data_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.got : { + *(.got) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.got1 : { + *(.got1) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.got2 : { + *(.got2) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.eh_frame : { + *(.eh_frame) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.jcr : { + *(.jcr) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.gcc_except_table : { + *(.gcc_except_table) +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.sdata : { + . = ALIGN(8); + __sdata_start = .; + *(.sdata) + *(.sdata.*) + *(.gnu.linkonce.s.*) + __sdata_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.sbss (NOLOAD) : { + . = ALIGN(4); + __sbss_start = .; + *(.sbss) + *(.sbss.*) + *(.gnu.linkonce.sb.*) + . = ALIGN(8); + __sbss_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.tdata : { + __tdata_start = .; + *(.tdata) + *(.tdata.*) + *(.gnu.linkonce.td.*) + __tdata_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.tbss : { + __tbss_start = .; + *(.tbss) + *(.tbss.*) + *(.gnu.linkonce.tb.*) + __tbss_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.bss (NOLOAD) : { + . = ALIGN(4); + __bss_start = .; + *(.bss) + *(.bss.*) + *(.gnu.linkonce.b.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 ); + +_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 ); + +/* Generate Stack and Heap definitions */ + +.heap (NOLOAD) : { + . = ALIGN(8); + _heap = .; + _heap_start = .; + . += _HEAP_SIZE; + _heap_end = .; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +.stack (NOLOAD) : { + _stack_end = .; + . += _STACK_SIZE; + . = ALIGN(8); + _stack = .; + __stack = _stack; +} > ilmb_cntlr_Mem_dlmb_cntlr_Mem + +_end = .; +} + diff --git a/software/src/main.c b/software/src/main.c new file mode 100644 index 0000000..146718d --- /dev/null +++ b/software/src/main.c @@ -0,0 +1,268 @@ +#include +#include +#include + +XIOModule gpo; + +int8_t x = 0; +int8_t y = 0; +int8_t scroll = 0; + +uint8_t reversed = 0; +uint8_t foreground = 0b111; +uint8_t background = 0; + +uint16_t properties = 0; + +void commit() { + XIOModule_DiscreteSet(&gpo, 3, 1); + XIOModule_DiscreteClear(&gpo, 3, 1); +} + +void calculate_properties() { + if (reversed) { + properties = ((foreground << 4) + background) << 8; + } else { + properties = ((background << 4) + foreground) << 8; + } +} + +void set_foreground(uint8_t color) { + foreground = color; + + calculate_properties(); +} + +void set_background(uint8_t color) { + background = color; + + calculate_properties(); +} + +void reverse(uint8_t enable) { + reversed = enable; + + calculate_properties(); +} + +void clear_screen() { + reverse(0); + set_foreground(0b111); + set_background(0); + XIOModule_DiscreteWrite(&gpo, 1, 0); + XIOModule_DiscreteWrite(&gpo, 2, 0); + XIOModule_DiscreteSet(&gpo, 3, 1); + + for (int y = 0; y < (45+2); ++y) { + int16_t temp = (y << 8); + for (int x = 0; x < (80+24); ++x) { + XIOModule_DiscreteWrite(&gpo, 2, temp + x); + } + } + + XIOModule_DiscreteClear(&gpo, 3, 1); + + x = 0; + y = 0; + scroll = 0; + XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x); + XIOModule_DiscreteWrite(&gpo, 4, scroll); +} + +void clear_eol() { + reverse(0); + set_foreground(0b111); + set_background(0); + + int16_t temp = (y << 8); + + XIOModule_DiscreteWrite(&gpo, 1, 0); + XIOModule_DiscreteWrite(&gpo, 2, temp + x); + XIOModule_DiscreteSet(&gpo, 3, 1); + + for (int i = x; i < (80+24); ++i) { + XIOModule_DiscreteWrite(&gpo, 2, temp + i); + } + + XIOModule_DiscreteClear(&gpo, 3, 1); +} + +void write(uint8_t c) { + XIOModule_DiscreteWrite(&gpo, 1, properties + c); + XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x); + commit(); +} + +void next() { + x++; + if (x >= 80) { + y++; + x %= 80; + } + + if (y >= 45) { + y--; + scroll = (scroll + 1) % 45; + XIOModule_DiscreteWrite(&gpo, 4, scroll); + clear_eol(); + } +} + +// @todo This does not appear to work quite correctly +void previous() { + x--; + if (x < 0) { + y--; + x %= 80; + } + + if (y < 0) { + y = 0; + x = 0; + } +} + +uint8_t data = 0; +uint8_t had = 0; +uint8_t escape = 0; +uint8_t escape_parameter_1 = 0; +uint8_t escape_parameter_2 = 0; + +void clock() { + uint8_t io_write = XIOModule_DiscreteRead(&gpo, 3); + if (io_write && !had) { + XIOModule_DiscreteClear(&gpo, 3, 2); + had = 1; + data = XIOModule_DiscreteRead(&gpo, 1) & 0xFF; + + if (escape == 1) { + if (data == '[') { + escape = 2; + } else { + escape = 0; + } + } else if (escape) { + switch (data) { + // For now we are only going to implement what we actually use + case 'K': + // Assume parameter 0 + clear_eol(); + escape = 0; + break; + + case 'H': + if (escape_parameter_1 == 0) { + escape_parameter_1 = 1; + } + + if (escape_parameter_2 == 0) { + escape_parameter_2 = 1; + } + + x = escape_parameter_1 - 1; + y = escape_parameter_2 - 1; + escape = 0; + break; + + case 'm': + if (escape_parameter_1 == 0) { + reverse(0); + set_foreground(0b111); + set_background(0); + } else if (escape_parameter_1 == 7) { + reverse(1); + } else if (escape_parameter_1 >= 30 && escape_parameter_1 <= 37) { + set_foreground(escape_parameter_1 - 30); + } else if (escape_parameter_1 >= 40 && escape_parameter_1 <= 47) { + set_background(escape_parameter_1 - 40); + } else if (escape_parameter_1 >= 90 && escape_parameter_1 <= 97) { + set_foreground(escape_parameter_1 - 90 + 8); + } else if (escape_parameter_1 >= 100 && escape_parameter_1 <= 107) { + set_background(escape_parameter_1 - 100 + 8); + } + escape = 0; + break; + + case 'J': + // Assume parameter 2 + clear_screen(); + escape = 0; + break; + + case '0' ... '9': + escape_parameter_1 *= 10; + escape_parameter_1 += (data - 48); + break; + + case ';': + escape_parameter_2 = escape_parameter_1; + escape_parameter_1 = 0; + break; + + default: + escape = 0; + break; + } + } else { + switch (data) { + case '\n': + y++; + if (y >= 45) { + y--; + scroll = (scroll + 1) % 45; + XIOModule_DiscreteWrite(&gpo, 4, scroll); + clear_eol(); + } + break; + + case '\r': + x = 0; + break; + + case 0x08: + previous(); + break; + + case 0x1B: + escape = 1; + escape_parameter_1 = 0; + escape_parameter_2 = 0; + // Handle escape code + break; + + default: + write(data); + next(); + break; + } + } + XIOModule_DiscreteWrite(&gpo, 2, (y << 8) + x); + } else if (had && !io_write) { + had = 0; + XIOModule_DiscreteSet(&gpo, 3, 2); + } +} + +int main() { + XIOModule_Initialize(&gpo, XPAR_IOMODULE_0_DEVICE_ID); // Initialize the GPO module + + microblaze_register_handler(XIOModule_DeviceInterruptHandler, + XPAR_IOMODULE_0_DEVICE_ID); // register the interrupt handler + + XIOModule_Start(&gpo); // start the GPO module + + XIOModule_Connect(&gpo, XIN_IOMODULE_GPI_2_INTERRUPT_INTR, clock, + NULL); // register timerTick() as our interrupt handler + XIOModule_Enable(&gpo, XIN_IOMODULE_GPI_2_INTERRUPT_INTR); // enable the interrupt + + microblaze_enable_interrupts(); // enable global interrupts + + // Clear the screen + clear_screen(); + + XIOModule_DiscreteSet(&gpo, 3, 2); + + while (1) { + + } +}