Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // =========================== INTERRUPT ID-evi ===========================
- #define TIMERPS_INT_ID #29 /* Private timer interrupt ID */
- #define XGPIOPS_INT_ID #52 /* GPIO interrupt ID */
- #define XIICPS_INT_ID #57 /* I2C interrupt ID */
- #define XSPIPS_INT_ID #58 /* SPI interrupt ID */
- #define XUARTPS_INT_ID #59 /* UART interrupt ID */
- // ===================== BAZNE ADRESE I OFFSETI SKLOPOVA =====================
- // CPU interface control (za prekide):
- #define ICC_ICR_BASEADDR #0xF8F00100 /* CPU interface control base address */
- #define ICC_IAR_OFFSET #0xC /* Interrupt acknowledge register */
- #define ICC_EOIR_OFFSET #0x10 /* End of interrupt register */
- // UART:
- #define XUARTPS_BASEADDR #0xE0000000
- //#define XUARTPS_CR_OFFSET #0x0 /* UART Control Register */
- #define XUARTPS_MR_OFFSET #0x4 /* UART Mode Register */
- #define XUARTPS_IER_OFFSET #0x8 /* Interrupt Enable Register */
- #define XUARTPS_IDR_OFFSET #0xC /* Interrupt Disable Register */
- #define XUARTPS_IMR_OFFSET #0x10 /* Interrupt Mask Register */
- #define XUARTPS_ISR_OFFSET #0x14 /* Channel Interrupt Status Register */
- #define XUARTPS_BAUDGEN_OFFSET #0x18 /* Baud Rate Generator Register */
- #define XUARTPS_RXTOUT_OFFSET #0x1C /* Receiver Timeout Register */
- #define XUARTPS_RXWM_OFFSET #0x20 /* Receiver FIFO Trigger Level Register*/
- #define XUARTPS_MODEMCR_OFFSET #0x24 /* Modem Control Register */
- #define XUARTPS_MODEMSR_OFFSET #0x28 /* Modem Status Register */
- #define XUARTPS_SR_OFFSET #0x2C /* Channel Status Register */
- #define XUARTPS_FIFO_OFFSET #0x30 /* Transmit and Receive FIFO*/
- #define Baud_rate_divider_reg0 #0x34 /* Baud Rate Divider Register */
- #define Flow_delay_reg0 #0x38 /* Flow Control Delay Register */
- #define TX_FIFO_trigger_level0 #0x44 /* Transmitter FIFO Trigger Level Register */
- // GPIO:
- #define XGPIOPS_BASEADDR #0xE000A000 /* GPIO base address */
- #define XGPIOPS_INT_TYPE_OFFSET #0x29C /* GPIO interrupt type register offset for bank 2 */
- #define XGPIOPS_INT_POL_OFFSET #0x2A0 /* GPIO interrupt polarity register offset for bank 2 */
- #define XGPIOPS_INT_EN_OFFSET #0x290 /* GPIO interrupt enable register offset for bank 2 */
- #define XGPIOPS_INT_EDGE_ANY #0x2A4 /* GPIO any interrupt edge register offset for bank 2 */
- #define XGPIOPS_DIRM_OFFSET #0x284 /* GPIO direction mode register offset for bank 2 */
- #define XGPIOPS_OUTEN_OFFSET #0x288 /* GPIO direction mode register offset for bank 2 */
- #define XGPIOPS_DATA2_OFFSET #0x48 /* GPIO data 2 (bank 2) register offset */
- #define XGPIOPS_ISR2_OFFSET #0x298 /* GPIO interrupt status register 2 (for bank 2) offset */
- // CPU0 private timer:
- #define TIMERPS_BASEADDR #0xF8F00600 /* CPU private timer base address */
- //#define TIMERPS_LR_OFFSET #0x0 /* CPU private timer load register offset */
- #define TIMERPS_CR_OFFSET #0x4 /* CPU private timer counter register offset */
- #define TIMERPS_CNTRL_OFFSET #0x8 /* CPU private timer control register offset */
- #define TIMERPS_ISR_OFFSET #0xC /* CPU private timer interrupt status register offset*/
- // ====================== MY_CONSTANTS ======================
- #define PRIM_ADR #0x7FFFFFC /* Array of prime numbers up to sqrt(2^31) with first cell being it's size*/
- #define LIM #46340
- // ====================== TABLICA PREKIDNIH VEKTORA ======================
- .section .vectors, "ax"
- B _start // Reset vector
- B SERVICE_UND // Undefined instruction vector
- B SERVICE_SVC // Software interrrupt vector
- B SERVICE_ABT_INST // Aborted prefetch vector
- B SERVICE_ABT_DATA // Aborted data vector
- .word 0 // Unused vector
- B SERVICE_IRQ // IRQ interrupt vector
- B SERVICE_FIQ // FIQ interrupt vector
- // ============================ POCETAK RESET VEKTORA ============================
- .text
- .global _start
- _start:
- // Postavljanje pokazivaca stoga za IRQ i SVC nacin rada
- MOV R1, #0b11010010 // MODE = IRQ
- MSR CPSR_c, R1 // Spremi u CPSR_c
- LDR SP, =0xFFFFFFF - 3 // Postavi IRQ stog
- // Postavi u SVC nacin rada
- MOV R1, #0b11010011 // MODE = SVC
- MSR CPSR, R1 // Spremi u CPSR
- LDR SP, =0x3FFFFFF - 3 // Postavi SVC stog
- BL CONFIG_GIC // Konfiguriraj ARM GIC
- // Omoguci prekide na GPIO sklopu za tipku 0
- LDR R0, =XGPIOPS_BASEADDR // GPIO adresa
- MOV R1, #0b11110000 // Kontrolna rijec
- STR R1, [R0, XGPIOPS_INT_TYPE_OFFSET] // Type
- STR R1, [R0, XGPIOPS_INT_POL_OFFSET] // Polarity
- STR R1, [R0, XGPIOPS_INT_EN_OFFSET] // Enable
- MOV R1, #0
- STR R1, [R0, XGPIOPS_INT_EDGE_ANY] // Any
- // Postavi GPIO izlaze
- MOV R1, #0b111111 // Kontrolna rijec
- MOV R1, R1, LSL #11
- STR R1, [R0, XGPIOPS_DIRM_OFFSET] // DIRM - postavi smjer
- STR R1, [R0, XGPIOPS_OUTEN_OFFSET] // OUTEN - omogu�i izlaze
- // Omoguci IRQ prekide na procesoru
- MOV R0, #0b01010011 // MODE = SVC
- MSR CPSR_c, R0
- MOV R0, #0
- LDR R1, =PRIM_ADR
- STR R0, [R1]
- // ========================= PROSTOR ZA PISANJE KODA =========================
- MAIN:
- /* Initialize dynamica array of prim numbers */
- MOV R0, #0
- LDR R1, =PRIM_ADR
- STR R0, [R1]
- MOV R2, #2
- PUSH {R2}
- BL APPEND_PRIM
- ADD SP, SP, #4
- /* Set counter (R1)*/
- MOV R1, #3
- IDLE:
- BL IS_RUNNING
- PUSH {R1}
- BL IS_PRIM
- ADD SP, SP, #4
- ADD R1, R1, #1
- CMP R1, #500
- BNE IDLE // "koristan posao"
- // ===================== KRAJ PROSTORA ZA PISANJE KODA =======================
- /* potporgrami */
- IS_PRIM:
- PUSH {R1 - R4, LR}
- LDR R4, [SP, #0x14]
- LDR R1, =PRIM_ADR
- LDR R2, [R1], #4
- ADD R1, R1, R2
- TEST_LOOP:
- LDR R3, [R1, -R2]
- SUB R2, R2, #4
- PUSH {R3}
- PUSH {R4}
- BL MOD
- ADD SP, SP, #8
- CMP R0, #0
- BEQ OUT_PRIM
- CMP R2, #0
- BGT TEST_LOOP
- PUSH {R4}
- BL APPEND_PRIM
- ADD SP, SP, #4
- OUT_PRIM:
- POP {R1 - R4, PC}
- // potprogram za dodavanje elementa na dinamicki array prostih brojeva, parametar prima preko stoga
- APPEND_PRIM:
- PUSH {R0 - R2, LR}
- LDR R0, [SP, #0x10]
- LDR R1, =LIM
- CMP R0, R1
- BLGE APPEND_PRIM_OUT
- LDR R1, =PRIM_ADR
- LDR R2, [R1], #4
- STR R0, [R1, R2]
- ADD R2, R2, #4
- STR R2, [R1, #-4]
- APPEND_PRIM_OUT:
- POP {R0 - R2, PC}
- // potprogram za racunanje modula, parametre prima preko stoga, a rezultat vraca preko r0
- // ako su parametri koje dohvaca sa stoga A i B, onda vraca A % B
- MOD:
- PUSH {R1 - R3, LR}
- LDR R0, [SP, #0x10]
- LDR R1, [SP, #0x14]
- MOV R2, #15
- POW_LOOP:
- MOV R3, R1, LSL R2
- SUB R2, R2, #1
- CMP R0, R3
- BLT POW_LOOP
- SUB_LOOP:
- SUB R0, R0, R3
- CMP R0, #0
- BEQ MOD_OUT
- CMP R3, #0
- BEQ MOD_OUT
- CMP R0, R3
- BGE SUB_LOOP
- CMP R2, #0
- BLGE POW_LOOP
- MOD_OUT:
- POP {R1 - R3, PC}
- IS_RUNNING:
- PUSH {R0 - R1, LR}
- MOV R1, #0b010010
- MOV R1, R1, LSL #10
- LDR R0, =XGPIOPS_BASEADDR
- STR R1, [R0, XGPIOPS_DATA2_OFFSET]
- POP {R0 - R1, PC}
- PAUSE_PROMPT:
- PUSH {R0 - R4, LR}
- MOV R1, #0b001001
- MOV R1, R1, LSL #10
- LDR R0, =XGPIOPS_BASEADDR
- STR R1, [R0, XGPIOPS_DATA2_OFFSET]
- PAUSED:
- B PAUSED
- // poraditi na ovome
- POP {R0 - R4, PC}
- /* Potprogrami za obradu prekida */
- /*--- Undefined instructions --------------------------------------------------*/
- SERVICE_UND:
- B SERVICE_UND
- /*--- Software interrupts -----------------------------------------------------*/
- SERVICE_SVC:
- B SERVICE_SVC
- /*--- Aborted data reads ------------------------------------------------------*/
- SERVICE_ABT_DATA:
- B SERVICE_ABT_DATA
- /*--- Aborted instruction fetch -----------------------------------------------*/
- SERVICE_ABT_INST:
- B SERVICE_ABT_INST
- /*--- IRQ ---------------------------------------------------------------------*/
- SERVICE_IRQ:
- PUSH {R0-R7, LR}
- LDR R4, =ICC_ICR_BASEADDR
- LDR R5, [R4, ICC_IAR_OFFSET] // Dohvacanje ID-a prekida
- FPGA_IRQ1_HANDLER:
- // ===================== PREKIDNA RUTINA - DOZNATI TKO JE GENERIRAO PREKID ==================
- CMP R5, XGPIOPS_INT_ID // 52 - ID za GPIO
- BEQ GPIO_INT
- UNEXPECTED:
- BNE UNEXPECTED // Nepoznati prekid - vrti se zauvijek
- GPIO_INT:
- LDR R0, =XGPIOPS_BASEADDR // GPIO adresa
- LDR R1, [R0, XGPIOPS_DATA2_OFFSET] // Ucitaj stanje na GPIO
- MOV R1, R1, LSR #4 // Dohvati bitove gumba
- // pauza
- MOV R2, #0
- ANDS R2, R1, #0b0001
- //BLPL PAUSE_PROMPT
- LDR R1, [R0, XGPIOPS_ISR2_OFFSET] // Dojavi kraj prekida na GPIO
- STR R1, [R0, XGPIOPS_ISR2_OFFSET]
- EXIT_IRQ:
- STR R5, [R4, ICC_EOIR_OFFSET] // ICCEOIR - End of interrupt register
- POP {R0-R7, LR}
- SUBS PC, LR, #4 // povratak iz prekida
- /*--- FIQ ---------------------------------------------------------------------*/
- SERVICE_FIQ:
- B SERVICE_FIQ
- // Konfiguracija Generic Interrupt Controller (GIC)
- CONFIG_GIC:
- PUSH {LR}
- /* Postavljanje prekida za GPIO tipke (ID 52):
- * 1. Postavi ciljani procesor na cpu0 u ICDIPTRn registru
- * 2. Omogu�i prekide u ICDISERn registru */
- /* CONFIG_INTERRUPT (int_ID (R0), CPU_target (R1)); */
- MOV R0, #52 // Interrupt ID = 52
- MOV R1, #1 // bit-mask; bit 0 ozna�ava cpu0
- BL CONFIG_INTERRUPT
- /* Postavi GIC CPU su�elje */
- LDR R0, =0xF8F00100 // Osnovna adresa CPU su�elja (ICC)
- /* Omogu�avanje prekida svih proriteta */
- LDR R1, =0xFFFF // ICCPMR - Interrupt Priority Mask Register
- STR R1, [R0, #0x04]
- // Prenesi prekide na procesor
- MOV R1, #1
- STR R1, [R0] // ICCICR - CPU Interface Control Register
- LDR R0, =0xF8F01000 // ICDDCR - Distributor Control Register
- STR R1, [R0] // Omogu�avanje distributora
- POP {PC}
- /*
- * Postavljaju se Interrupt Set Enable Registers (ICDISERn) i
- * Interrupt Processor Target Registers (ICDIPTRn).
- *
- * Argumenti:
- * R0 = Interrupt ID, N
- * R1 = CPU target
- */
- CONFIG_INTERRUPT:
- PUSH {R4-R5, LR}
- /* Postavi Interrupt Set-Enable Registers (ICDISERn).
- * reg_offset = (integer_div(N / 32) * 4
- * value = 1 << (N mod 32) */
- LSR R4, R0, #3 // Izra�unaj reg_offset
- BIC R4, R4, #3 // R4 = reg_offset
- LDR R2, =0xF8F01100
- ADD R4, R2, R4 // R4 = ICDISER
- AND R2, R0, #0x1F // N mod 32
- MOV R5, #1 // Omogu�i
- LSL R2, R5, R2 // R2 = maska
- // Koristi se adresa u R4 i maska u R2 da se postavi to�an bit u GIC registru
- LDR R3, [R4]
- ORR R3, R3, R2
- STR R3, [R4]
- /* Postavi Interrupt Processor Targets Register (ICDIPTRn)
- * reg_offset = integer_div(N / 4) * 4
- * index = N mod 4 */
- BIC R4, R0, #3 // R4 = reg_offset
- LDR R2, =0xF8F01800
- ADD R4, R2, R4 // R4 = adresa rije�i ICDIPTR
- AND R2, R0, #0x3 // N mod 4
- ADD R4, R2, R4 // R4 = adresa bajta ICDIPTR
- /* Koristi se adresa u R4 i vrijednost u R2 da se postavi odgovaraju�i bajt */
- STRB R1, [R4]
- POP {R4-R5, PC}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement