# Animacija s komponentami VGAram, axi_fill in VGAmouse Primer sistema za prikaz slike na izhodu VGA razvojne plošče ZedBoard s komponento, ki bere slikovne točke iz BRAM. Primerjava premikanja (animacije) kvadrata na zaslonu, ki jo izvaja CPU s pisanjem posameznih točk in strojna komponenta za risanje kvadrata. Uporaba prekinitev za tekočo animacijo. Projekt je narejen za ploščo ZedBoard, poleg komponent iz knjižnic potrebujemo še: [VGAram](src/VGAram_1.2.zip). **TODO:** *manjka podrobnejši opis sistema in uporabljenih komponent.* ![](./img/bd_vga.png) [Celoten blokovni diagram](img/bd_vga_irq.png) ## Aplikacija V kodi so komentarji z razlago nastavitev prekinitev in uporabe prekinitvene rutine. Na zaslonu se prikažeta dva kvadrata - enega izrisuje strojna komponenta in ga premikamo v prekinitveni rutini, drugega pa rišemo s pisanjem v BRAM znotraj neskončne zanke. Prekinitev se proži ob koncu prikaza posamezne slike na zaslon, da je premikanje usklajeno z osveževanjem slike. Če povečujemo velikost kvadrata, počasnejše nastavljanje točk s pisanjem v BRAM ne more več slediti. ```c #include <stdio.h> #include "xparameters.h" #include "xil_io.h" #include "xscugic.h" #include "xil_exception.h" #include "sleep.h" // definiraj registre axi_fill #define RGB XPAR_VGA_AXI_FILL_0_S00_AXI_BASEADDR #define SIZE XPAR_VGA_AXI_FILL_0_S00_AXI_BASEADDR+4 #define XP XPAR_VGA_AXI_FILL_0_S00_AXI_BASEADDR+8 #define YP XPAR_VGA_AXI_FILL_0_S00_AXI_BASEADDR+12 // definiraj BRAM #define BRAM XPAR_VGA_AXI_BRAM_CTRL_0_S_AXI_BASEADDR // definiraj GPIO_1 (VGA MOUSE) #define MX XPAR_AXI_GPIO_1_BASEADDR #define MY XPAR_AXI_GPIO_1_BASEADDR+8 // definicije za prekinitveni krmilnik (VGA RAM) #define INTC_INTERRUPT_ID XPAR_FABRIC_VGA_VGARAM_0_IRQ_INTR // 61 #define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID // =0 static XScuGic Intc; // prekinitvena struktura int ir = 0; // zastavica za status prekinitve void service(void *InstancePtr) { // prekinitvena rutina static int x = 0; ir = 1; // prekinitev sprozena Xil_Out8(XP, x); // brisi kvadrat na koordinati x Xil_Out8(RGB, 0); usleep(500); // cakaj vsaj size*size*2/50 us, da se izvede Xil_Out8(XP, ++x); // narisi kvadrat na x+1 Xil_Out8(RGB, 0x0f); Xil_Out8(MX, x); // premakni kurzor miske Xil_Out8(MY, 255-x); } int SetupInterruptSystem() { // nastavi prekinitve int result; XScuGic *IntcInstancePtr = &Intc; XScuGic_Config *IntcConfig; IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID); if (IntcConfig == NULL) { return XST_FAILURE; } result = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig, IntcConfig->CpuBaseAddress); if (result != XST_SUCCESS) { return XST_FAILURE; } XScuGic_SetPriorityTriggerType(IntcInstancePtr, INTC_INTERRUPT_ID,0x00, 0x3); /* Povezi prekinitveno rutino (service) */ result = XScuGic_Connect(IntcInstancePtr, INTC_INTERRUPT_ID, (Xil_ExceptionHandler) service, 0); if (result != XST_SUCCESS) { return result; } /* Omogoci prekinitve */ XScuGic_Enable(IntcInstancePtr, INTC_INTERRUPT_ID); Xil_ExceptionInit(); Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT, (Xil_ExceptionHandler)XScuGic_InterruptHandler, IntcInstancePtr); Xil_ExceptionEnable(); /* omogoci nekriticne izjeme */ return XST_SUCCESS; } int main() { int size = 100; // velikost kvadratov char *c; int i, j, xk=0; Xil_Out8(XP, 0); // narisi crn kvadrat, da se pocisti cel zaslon Xil_Out8(YP, 0); Xil_Out8(SIZE, 255); Xil_Out8(RGB, 0); usleep(3000); // cakaj vsaj 256*256*2/50 us Xil_Out8(SIZE, size); // nastavi prekinitve if (SetupInterruptSystem() != XST_SUCCESS) { return XST_FAILURE; } // animacija v neskoncni zanki while(1) { while(ir==0); // cakaj novo prekinitev in ir=0; // ponastavi zastavico for (j=0; j<size; j++) // brisi kvadrat velikosti size na (xk-1, 100) for (i=0; i<size; i++) { c = (char *) BRAM + ((100+j)<<8) + i + (xk-1); *c = 0x0; } for (j=0; j<size; j++) // narisi kvadrat velikosti size na (xk, 100) for (i=0; i<size; i++) { c = (char *) BRAM + ((100+j)<<8) + i + xk; *c = 0xff; } usleep(10000); // pavza mora biti krajsa od periode prekinitev (1 frame = 13.8 ms) xk++; } return 0; } ```