rendered paste body/* ----------------------------------------------------------
@ 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: