/* ---------------------------------------------------------- @ led_blink_irq.s: Utilisation des interruptions AIC, d'un @ des trois timers et du PIO ---------------------------------------------------------- */ .include "carte.inc" .global _start @ Pour éviter le warning de arm-elf-ld _start: main: @ Pour le point d'arrêt automatique @mov r13,#0x20000 @ pile en 0x20000 adr r9, tableau ldr r8, =ft @ initialisation des leds @ ----------------------- ldr r1,=PIO_BASE ldr r0,=(LED8|LED7|LED6|LED5|LED4|LED2|LED3|LED1) str r0,[r1, #PIO_PER] @ Autoriser les ports str r0,[r1, #PIO_OER] @ P6 et P16 en sortie @str r0,[r1, #PIO_CODR]@ eteindre les leds 8 et 1 @ initialisation du timer1 @ ----------------------- ldr r1,=TC1_BASE mov r0,#0b10 str r0,[r1, #TC_CCR] @ interdire l'horloge du compteur mvn r0,#0x0 str r0,[r1, #TC_IDR] @ interdire la génération d'interruption ldr r0,[r1, #TC_SR] @ lire le SR de TC1 ldr r0,=0x4004 str r0,[r1, #TC_CMR] @ TC1 utilise MCK/1024 et redémarrage auto mov r0,#1 str r0,[r1, #TC_CCR] @ Autoriser l'horloge mov r0,#0x10 str r0,[r1, #TC_IER] @ Valider l'interruption de comparaison avec RC @ Initialisation AIC @ ----------------------- ldr r2,=AIC_BASE mov r0,#0b100000 str r0,[r2, #AIC_IDCR] @ Interdire l'interruption du Timer1 dans l'AIC adr r0,timer1_irq_handler @ Mettre l'adresse de la routine d'interruption str r0,[r2, #AIC_SVR5] @ dans AIC_SVR5 (vecteur relatif à TC1_IRQ) mov r0,#0x04 @ Priorité 4 pour l'interruption TC1 str r0,[r2, #AIC_SMR5] mov r0,#0b100000 str r0,[r2, #AIC_ICCR] @ RAZ de l'interruption TC1 str r0,[r2, #AIC_IECR] @ Autorise l'interruption TC1 @ paramètres de timing du timer1 @ ----------------------- ldr r0,=64453 @ 64453 * MCK/1024 -> une seconde str r0,[r1, #TC_RC] @ Placer le délai dans le registre C mov r0,#0b100 @ Mise à 1 bu bit 2 de CCR str r0,[r1, #TC_CCR] @ -> RAZ compteur et démarrage @ Tâche de fond boucle: b boucle @ ... @ Fin de la tâche de fond @ ------------------------ exit: @ Retour â Angel par exception (appel systême) mov r0, #0x18 ldr r1, =0x20026 swi 0x123456 @ =============================================================== @ Fin du programme principal @ =============================================================== @ =============================================================== @ Gestionnaire de l'interruption du timer 1 @ =============================================================== timer1_irq_handler: @ ------------------------ @- Ajuster et sauvegarder le registre de retour du mode IRQ dans la pile IRQ sub r14, r14, #4 @ r14 pointe une instruction trop loin stmfd sp!, {r14} @ sauvegarder l'adresse de retour dans la pile IRQ @ Sauvegarder SPSR et R0 dans la pile IRQ mrs r14, spsr stmfd sp!, {r0, r14} @ passer en mode systême mrs r14, cpsr orr r14, r14, #0b11111 @ (mode systême) msr cpsr, r14 @ Sauvegarde de registres dans la pile systême stmfd sp!, { r1, r2, r14} @ autoriser les interruptions mrs r14, cpsr bic r14, r14, #0x80 @ CPSR[I] <- 0 msr cpsr, r14 @ ----------------------- ldr r1,=TC1_BASE ldr r0,[r1, #TC_SR] @ Lecture SR pour le remettre à 0 @ (pour signifier qu'on traite l'IT) ldr r1,=PIO_BASE ldr r0, =LED1|LED2|LED3|LED4 ldrb r2, [r9], #1 mov r3, r2, lsl #16 and r3, r0, r3 ldr r0, =LED5|LED6|LED7|LED8 mov r4, r2, lsr #1 and r4, r4, r0 orr r0, r4, r3 str r0, [r1, #PIO_CODR] mvn r0, r0 str r0, [r1, #PIO_SODR] @ Fin interruption @ ---------------- cmp r9, r8 ldreq r9, =tableau fin_irq: @- Interdire les interruptions mrs r0, cpsr orr r0, r0, #0b10000000 @ CPSR[I] <- 1 msr cpsr, r0 @ Restaurer les registres depuis la pile systême ldmfd sp!, { r1, r2, r14} @- repasser en mode IRQ mrs r0, cpsr bic r0, r0, #0x1F @ CPSR[MO..M4] <- 0b00000 orr r0, r0, #0b10010 @ CPSR[MO..M4] <- 0b10010 msr cpsr, r0 @ Indiquer la prise en compte de l'interruption à l'AIC @ = écriture de n'importe quoi dans AIC_EOICR ldr r0, =AIC_BASE str r0, [r0, #AIC_EOICR] @ Restaurer SPSR_irq et r0 à partir de la pile IRQ ldmfd sp!, {r0, r14} msr spsr, r14 @ Restaurer LR_irq depuis la pile IRQ et le mettre directement dans le PC ldmfd sp!, {pc}^ @ Fin du sous_programme d'interruption tableau: .byte 1, 3, 7, 15, 0, 15, 0, 15, 0 ft: